From f85760fe24b6fe634ab74510d8b3b7727039e6b2 Mon Sep 17 00:00:00 2001 From: Donavan Becker Date: Tue, 3 Mar 2026 22:28:14 -0600 Subject: [PATCH 1/3] v4.0.0 * Complete rewrite with unified hybrid BLE/API architecture * No backward compatibility with v3.x - migration required * Single `SwitchBot` class replaces `SwitchBotBLE` and `SwitchBotOpenAPI` * Device access via `switchbot.devices` manager pattern * Full TypeScript rewrite with comprehensive type definitions * **Hybrid Architecture**: Unified BLE-first approach with automatic OpenAPI fallback * **Automatic Discovery**: Combined BLE + OpenAPI device discovery in single call * **Smart Fallback**: Commands automatically retry via API when BLE fails * **Device Manager**: Centralized device management with `get()`, `list()`, and `clear()` methods * **Expanded Device Coverage**: Added support and parsing updates across newly modeled devices and accessories in the v4 architecture. * **macOS BLE Support**: Enabled BLE functionality on macOS in addition to Linux * Platform detection now includes macOS (`darwin`) using `@stoprocent/noble` * BLE now works on Linux and macOS systems * Windows remains unsupported for BLE operations * **Bot Password Protection**: Added BLE password support for Bot (`WoHand`) devices * Password encryption using CRC32 checksums * Password validation for 4 alphanumeric characters, case-sensitive * Methods: `setPassword()`, `clearPassword()`, `hasPassword()` * Automatic encrypted command execution when password is set * Example: `examples/bot-password.js` * Based on [homebridge-switchbot PR #1337](https://github.com/OpenWonderLabs/homebridge-switchbot/pull/1337) * **Advanced Resilience Features**: Enterprise-grade reliability enhancements * Retry logic with exponential backoff and jitter * Circuit breaker pattern to prevent cascading failures * Connection intelligence tracking per-device success and failure rates * Custom fallback handler system for logging, metrics, and alerting * Intelligent connection selection based on historical performance * **Event-Driven**: EventEmitter-based architecture for discovery and command events * **TypeScript Native**: Written in TypeScript with full type safety and exports * **Custom Errors**: Specific error classes for better error handling * **BLE-Only Mode**: Works without OpenAPI credentials on Linux/macOS systems * **API-Only Mode**: Works without BLE on Windows systems * **Exports and API Surface Updates**: Updated `src/index.ts` exports for final v4 public API packaging. * **Comprehensive Examples**: Updated and aligned example files for v4 usage patterns. * Complete ES2022 module implementation * Improved error handling with custom error classes * Better connection management and timeout handling * Enhanced logging with configurable log levels * Hardened dependency graph with security overrides for vulnerable transitive packages * Full JSDoc documentation coverage * Comprehensive TypeScript type definitions for all devices * Reworked test suite structure and coverage for APIs, devices, and utilities * Auto-formatting and linting with @antfu/eslint-config * Updated README with v4 quick start and migration guide * 6 usage examples in `examples/` directory * Migration guide from v3.x to v4.0.0 * Added password protection section to [BLE.md](BLE.md) * Updated [README.md](README.md) with password examples * Created comprehensive password protection example * Updated examples index with `bot-password.js` * Updated platform support documentation to reflect macOS BLE support * Updated Linux-only references to Linux/macOS where applicable * Added comprehensive prerequisites guidance for BLE setup on macOS and Linux * macOS: Xcode and Bluetooth permissions requirements * Linux: system packages, non-root setup, and Raspberry Pi notes * Based on [@stoprocent/noble prerequisites](https://github.com/stoprocent/noble?tab=readme-ov-file#prerequisites) * Full API documentation via TypeDoc * Added 14 comprehensive password protection tests * Validation for CRC32 encryption, command building, and response parsing * Extended fallback and retry behavior coverage across BLE/API paths * 58 test files and 243 passing tests at release validation **Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.8...v4.0.0 --- .github/copilot-instructions.md | 24 +- .github/workflows/beta-release.yml | 52 - .github/workflows/release.yml | 81 +- .github/workflows/stale.yml | 4 +- .npmignore | 8 + BLE.md | 940 +- CHANGELOG.md | 1408 +- OpenAPI.md | 304 +- README.md | 98 + docs/assets/hierarchy.js | 2 +- docs/assets/highlight.css | 33 +- docs/assets/icons.js | 2 +- docs/assets/icons.svg | 2 +- docs/assets/main.js | 4 +- docs/assets/navigation.js | 2 +- docs/assets/search.js | 2 +- docs/assets/style.css | 6 +- docs/classes/APIError.html | 6 + docs/classes/APINotAvailableError.html | 4 + docs/classes/Advertising.html | 21 - docs/classes/BLEConnection.html | 25 + docs/classes/BLENotAvailableError.html | 4 + docs/classes/BLEScanner.html | 17 + docs/classes/CommandFailedError.html | 6 + docs/classes/ConnectionTimeoutError.html | 5 + docs/classes/DeviceManager.html | 25 + docs/classes/DeviceNotFoundError.html | 4 + .../DeviceOverrideStateDuringConnection.html | 82 + docs/classes/DiscoveryError.html | 5 + docs/classes/ErrorUtils.html | 25 - docs/classes/OpenAPIClient.html | 66 + docs/classes/ParameterChecker.html | 69 - docs/classes/SequenceDevice.html | 92 + docs/classes/SwitchBot.html | 22 + docs/classes/SwitchBotBLE.html | 39 - docs/classes/SwitchBotError.html | 4 + docs/classes/SwitchBotOpenAPI.html | 57 - docs/classes/SwitchbotDevice.html | 160 +- docs/classes/ValidationError.html | 5 + docs/classes/ValidationUtils.html | 51 - docs/classes/WoAIHub.html | 116 + docs/classes/WoAirPurifier.html | 163 +- docs/classes/WoAirPurifierPM25.html | 117 + docs/classes/WoAirPurifierTable.html | 170 +- docs/classes/WoArtFrame.html | 103 + docs/classes/WoBlindTilt.html | 155 +- docs/classes/WoBulb.html | 181 +- docs/classes/WoCandleWarmerLamp.html | 122 + docs/classes/WoCeilingLight.html | 208 +- docs/classes/WoCirculatorFan.html | 89 + docs/classes/WoClimatePanel.html | 89 + docs/classes/WoContact.html | 132 +- docs/classes/WoCurtain.html | 158 +- docs/classes/WoFloorLamp.html | 103 + docs/classes/WoGarageDoorOpener.html | 94 + docs/classes/WoHand.html | 149 +- docs/classes/WoHub2.html | 132 +- docs/classes/WoHub3.html | 133 +- docs/classes/WoHubMiniMatter.html | 83 + docs/classes/WoHumi.html | 150 +- docs/classes/WoHumi2.html | 155 +- docs/classes/WoIOSensorTH.html | 134 +- docs/classes/WoKeypad.html | 133 +- docs/classes/WoKeypadVision.html | 83 + docs/classes/WoKeypadVisionPro.html | 83 + docs/classes/WoLeak.html | 133 +- docs/classes/WoPanTiltCamPlus3K.html | 122 + docs/classes/WoPlugMiniJP.html | 165 +- docs/classes/WoPlugMiniUS.html | 158 +- docs/classes/WoPresence.html | 140 +- docs/classes/WoRGBICBulb.html | 114 + docs/classes/WoRGBICNeonWireRopeLight.html | 126 + docs/classes/WoRGBICWWFloorLamp.html | 114 + docs/classes/WoRGBICWWStripLight.html | 114 + docs/classes/WoRelaySwitch1.html | 144 +- docs/classes/WoRelaySwitch1PM.html | 149 +- docs/classes/WoRelaySwitch2PM.html | 98 + docs/classes/WoRemote.html | 133 +- docs/classes/WoRemoteWithScreen.html | 116 + docs/classes/WoRollerShade.html | 95 + docs/classes/WoSensorTH.html | 126 +- docs/classes/WoSensorTHPlus.html | 127 +- docs/classes/WoSensorTHPro.html | 127 +- docs/classes/WoSensorTHProCO2.html | 127 +- docs/classes/WoSmartLock.html | 198 +- docs/classes/WoSmartLockLite.html | 91 + docs/classes/WoSmartLockPro.html | 202 +- docs/classes/WoSmartLockProWiFi.html | 95 + docs/classes/WoSmartLockVision.html | 91 + docs/classes/WoSmartLockVisionPro.html | 95 + docs/classes/WoSmartThermostatRadiator.html | 89 + docs/classes/WoStrip.html | 195 +- docs/classes/WoStripLight3.html | 103 + docs/classes/WoVacuum.html | 98 + docs/classes/WoVacuumK10Plus.html | 98 + docs/classes/WoVacuumK10Pro.html | 98 + docs/classes/WoVacuumK10ProCombo.html | 98 + docs/classes/WoVacuumK11Plus.html | 98 + docs/classes/WoVacuumK20.html | 98 + docs/classes/WoVacuumS10.html | 98 + docs/classes/WoVacuumS20.html | 98 + docs/classes/WoWaterDetector.html | 116 + docs/enums/LogLevel.html | 11 +- docs/enums/SwitchBotBLEModel.html | 15 +- docs/enums/SwitchBotBLEModelFriendlyName.html | 38 - docs/enums/SwitchBotBLEModelName.html | 18 +- docs/enums/SwitchBotModel.html | 51 - docs/functions/updateBaseURL.html | 6 +- docs/hierarchy.html | 2 +- docs/index.html | 46 +- docs/interfaces/APICommandRequest.html | 5 + docs/interfaces/APICommandResponse.html | 5 + docs/interfaces/APIDevice.html | 18 + docs/interfaces/APIDeviceStatus.html | 36 + docs/interfaces/APIErrorResponse.html | 5 + docs/interfaces/APIResponse.html | 5 + docs/interfaces/AdvertisementData.html | 3 - docs/interfaces/AirPurifierCommands.html | 6 + docs/interfaces/AirPurifierServiceData.html | 29 + docs/interfaces/AirPurifierStatus.html | 17 + docs/interfaces/BLEAdvertisement.html | 13 + docs/interfaces/BLEScanOptions.html | 10 + docs/interfaces/BLEServiceData.html | 27 + docs/interfaces/BlindTiltCommands.html | 7 + docs/interfaces/BlindTiltServiceData.html | 30 + docs/interfaces/BlindTiltStatus.html | 16 + docs/interfaces/BotCommands.html | 8 + docs/interfaces/BotServiceData.html | 27 + docs/interfaces/BotStatus.html | 14 + docs/interfaces/BulbCommands.html | 10 + docs/interfaces/BulbServiceData.html | 35 + docs/interfaces/BulbStatus.html | 16 + docs/interfaces/CeilingLightCommands.html | 10 + docs/interfaces/CeilingLightServiceData.html | 35 + docs/interfaces/CeilingLightStatus.html | 16 + docs/interfaces/Chars.html | 4 - .../interfaces/ColorLightServiceDataBase.html | 17 - docs/interfaces/CommandResult.html | 12 + docs/interfaces/ContactServiceData.html | 30 + docs/interfaces/ContactStatus.html | 15 + docs/interfaces/CurtainCommands.html | 8 + docs/interfaces/CurtainExtendedInfo.html | 4 + docs/interfaces/CurtainServiceData.html | 31 + docs/interfaces/CurtainStatus.html | 17 + docs/interfaces/DeviceInfo.html | 36 + docs/interfaces/DeviceListResponse.html | 4 + docs/interfaces/DiscoveryOptions.html | 14 + docs/interfaces/ErrorObject.html | 3 - docs/interfaces/HubServiceData.html | 31 + docs/interfaces/HubStatus.html | 15 + docs/interfaces/HumidifierCommands.html | 9 + docs/interfaces/HumidifierServiceData.html | 31 + docs/interfaces/HumidifierStatus.html | 18 + docs/interfaces/KeypadStatus.html | 13 + docs/interfaces/LeakServiceData.html | 28 + docs/interfaces/LeakStatus.html | 13 + docs/interfaces/LockBaseServiceData.html | 15 - docs/interfaces/LockCommands.html | 7 + docs/interfaces/LockServiceData.html | 29 + docs/interfaces/LockStatus.html | 15 + docs/interfaces/MeterServiceData.html | 30 + docs/interfaces/MeterStatus.html | 15 + docs/interfaces/MotionServiceData.html | 30 + docs/interfaces/MotionStatus.html | 14 + docs/interfaces/NobleTypes.html | 3 - docs/interfaces/Params.html | 6 - docs/interfaces/PlugCommands.html | 4 + docs/interfaces/PlugMiniServiceDataBase.html | 12 - docs/interfaces/PlugServiceData.html | 33 + docs/interfaces/PlugStatus.html | 16 + docs/interfaces/PresenceServiceData.html | 29 + docs/interfaces/PresenceStatus.html | 14 + docs/interfaces/PushRequest.html | 5 - docs/interfaces/PushResponseBody.html | 3 - docs/interfaces/RelaySwitchCommands.html | 6 + docs/interfaces/RelaySwitchServiceData.html | 30 + docs/interfaces/RelaySwitchStatus.html | 16 + docs/interfaces/RemoteStatus.html | 12 + docs/interfaces/Rule.html | 9 - docs/interfaces/SceneListResponse.html | 3 + docs/interfaces/ServiceData.html | 2 - docs/interfaces/StripCommands.html | 10 + docs/interfaces/StripServiceData.html | 35 + docs/interfaces/StripStatus.html | 16 + docs/interfaces/SwitchBotBLEDevice.html | 27 - docs/interfaces/SwitchBotConfig.html | 39 + docs/interfaces/SwitchBotScanner.html | 6 - .../TemperatureServiceDataBase.html | 10 - docs/interfaces/VacuumCommands.html | 8 + docs/interfaces/VacuumStatus.html | 16 + docs/interfaces/WebhookConfig.html | 4 + docs/interfaces/WebhookDetail.html | 6 - docs/interfaces/WebhookDetails.html | 7 + docs/interfaces/WebhookQueryResponse.html | 5 + docs/interfaces/WebhookSetupResponse.html | 5 + docs/interfaces/ad.html | 5 - docs/interfaces/body.html | 3 - docs/interfaces/bodyChange.html | 4 - docs/interfaces/deleteWebhookResponse.html | 4 - docs/interfaces/device.html | 7 - docs/interfaces/deviceList.html | 2 - docs/interfaces/deviceStatus.html | 19 +- docs/interfaces/deviceStatusRequest.html | 4 - docs/interfaces/deviceWebhook.html | 4 - docs/interfaces/deviceWebhookContext.html | 4 - docs/interfaces/devices.html | 4 - docs/interfaces/infraredRemoteList.html | 2 - docs/interfaces/irdevice.html | 5 - docs/interfaces/pushResponse.html | 5 - docs/interfaces/queryWebhookResponse.html | 4 - docs/interfaces/setupWebhookResponse.html | 4 - docs/interfaces/updateWebhookResponse.html | 4 - docs/interfaces/webhookRequest.html | 4 - docs/media/BLE.md | 940 +- docs/media/OpenAPI.md | 304 +- docs/modules.html | 2 +- docs/types/BLEDeviceServiceData.html | 1 - docs/types/CommandType.html | 2 - docs/types/ConnectionType.html | 2 + docs/types/MacAddress.html | 1 - docs/types/PhysicalDeviceType.html | 2 + docs/types/VirtualDeviceType.html | 2 + docs/types/airPurifier.html | 1 - docs/types/airPurifierPM25WebhookContext.html | 1 - docs/types/airPurifierServiceData.html | 1 - docs/types/airPurifierStatus.html | 1 - docs/types/airPurifierTable.html | 1 - .../airPurifierTablePM25WebhookContext.html | 1 - docs/types/airPurifierTableServiceData.html | 1 - docs/types/airPurifierTableStatus.html | 1 - docs/types/airPurifierTableVOC.html | 1 - docs/types/airPurifierTableVOCStatus.html | 1 - .../airPurifierTableVOCWebhookContext.html | 1 - .../types/airPurifierTableWebhookContext.html | 1 - docs/types/airPurifierVOC.html | 1 - docs/types/airPurifierVOCStatus.html | 1 - docs/types/airPurifierVOCWebhookContext.html | 1 - docs/types/airPurifierWebhookContext.html | 1 - docs/types/batteryCirculatorFan.html | 1 - .../batteryCirculatorFanServiceData.html | 1 - docs/types/batteryCirculatorFanStatus.html | 1 - .../batteryCirculatorFanWebhookContext.html | 1 - docs/types/blindTilt.html | 1 - docs/types/blindTiltServiceData.html | 1 - docs/types/blindTiltStatus.html | 1 - docs/types/blindTiltWebhookContext.html | 1 - docs/types/bot.html | 1 - docs/types/botServiceData.html | 1 - docs/types/botStatus.html | 1 - docs/types/botWebhookContext.html | 1 - docs/types/ceilingLight.html | 1 - docs/types/ceilingLightPro.html | 1 - docs/types/ceilingLightProServiceData.html | 1 - docs/types/ceilingLightProStatus.html | 1 - docs/types/ceilingLightProWebhookContext.html | 1 - docs/types/ceilingLightServiceData.html | 1 - docs/types/ceilingLightStatus.html | 1 - docs/types/ceilingLightWebhookContext.html | 1 - docs/types/circulatorFanStatus.html | 1 - docs/types/circulatorFanWebhookContext.html | 1 - docs/types/colorBulb.html | 1 - docs/types/colorBulbServiceData.html | 1 - docs/types/colorBulbStatus.html | 1 - docs/types/colorBulbWebhookContext.html | 1 - docs/types/contactSensor.html | 1 - docs/types/contactSensorServiceData.html | 1 - docs/types/contactSensorStatus.html | 1 - docs/types/contactSensorWebhookContext.html | 1 - docs/types/curtain.html | 1 - docs/types/curtain3.html | 1 - docs/types/curtain3ServiceData.html | 1 - docs/types/curtain3WebhookContext.html | 1 - docs/types/curtainServiceData.html | 1 - docs/types/curtainStatus.html | 1 - docs/types/curtainWebhookContext.html | 1 - docs/types/floorCleaningRobotS10.html | 1 - docs/types/floorCleaningRobotS10Status.html | 1 - .../floorCleaningRobotS10WebhookContext.html | 1 - docs/types/hub2.html | 1 - docs/types/hub2ServiceData.html | 1 - docs/types/hub2Status.html | 1 - docs/types/hub2WebhookContext.html | 1 - docs/types/hub3ServiceData.html | 1 - docs/types/humidifier.html | 1 - docs/types/humidifier2ServiceData.html | 1 - docs/types/humidifier2Status.html | 1 - docs/types/humidifier2WebhookContext.html | 1 - docs/types/humidifierServiceData.html | 1 - docs/types/humidifierStatus.html | 1 - docs/types/humidifierWebhookContext.html | 1 - docs/types/indoorCam.html | 1 - docs/types/indoorCameraWebhookContext.html | 1 - docs/types/keypad.html | 1 - docs/types/keypadDetectorServiceData.html | 1 - docs/types/keypadTouch.html | 1 - docs/types/keypadTouchWebhookContext.html | 1 - docs/types/keypadWebhookContext.html | 1 - docs/types/lock.html | 1 - docs/types/lockPro.html | 1 - docs/types/lockProServiceData.html | 1 - docs/types/lockProStatus.html | 1 - docs/types/lockProWebhookContext.html | 1 - docs/types/lockServiceData.html | 1 - docs/types/lockStatus.html | 1 - docs/types/lockWebhookContext.html | 1 - docs/types/meter.html | 1 - docs/types/meterPlus.html | 1 - docs/types/meterPlusServiceData.html | 1 - docs/types/meterPlusStatus.html | 1 - docs/types/meterPlusWebhookContext.html | 1 - docs/types/meterPro.html | 1 - docs/types/meterProCO2ServiceData.html | 1 - docs/types/meterProCO2Status.html | 1 - docs/types/meterProCO2WebhookContext.html | 1 - docs/types/meterProServiceData.html | 1 - docs/types/meterProStatus.html | 1 - docs/types/meterProWebhookContext.html | 1 - docs/types/meterServiceData.html | 1 - docs/types/meterStatus.html | 1 - docs/types/meterWebhookContext.html | 1 - docs/types/motionSensor.html | 1 - docs/types/motionSensorServiceData.html | 1 - docs/types/motionSensorStatus.html | 1 - docs/types/motionSensorWebhookContext.html | 1 - docs/types/onadvertisement.html | 1 - docs/types/ondiscover.html | 1 - docs/types/outdoorMeter.html | 1 - docs/types/outdoorMeterServiceData.html | 1 - docs/types/outdoorMeterStatus.html | 1 - docs/types/outdoorMeterWebhookContext.html | 1 - docs/types/panTiltCamWebhookContext.html | 1 - docs/types/pantiltCam.html | 1 - docs/types/pantiltCam2k.html | 1 - docs/types/plug.html | 1 - docs/types/plugMini.html | 1 - docs/types/plugMiniJPServiceData.html | 1 - docs/types/plugMiniJPWebhookContext.html | 1 - docs/types/plugMiniStatus.html | 1 - docs/types/plugMiniUSServiceData.html | 1 - docs/types/plugMiniUSWebhookContext.html | 1 - docs/types/plugStatus.html | 1 - docs/types/plugWebhookContext.html | 1 - docs/types/presenceSensor.html | 1 - docs/types/presenceSensorServiceData.html | 1 - docs/types/presenceSensorStatus.html | 1 - docs/types/presenceSensorWebhookContext.html | 1 - docs/types/relaySwitch1Context.html | 1 - docs/types/relaySwitch1PMContext.html | 1 - docs/types/relaySwitch1PMServiceData.html | 1 - docs/types/relaySwitch1PMStatus.html | 1 - docs/types/relaySwitch1ServiceData.html | 1 - docs/types/relaySwitch1Status.html | 1 - docs/types/remote.html | 1 - docs/types/remoteServiceData.html | 1 - docs/types/robotVacuumCleanerS1.html | 1 - docs/types/robotVacuumCleanerS1Plus.html | 1 - .../types/robotVacuumCleanerS1PlusStatus.html | 1 - ...obotVacuumCleanerS1PlusWebhookContext.html | 1 - docs/types/robotVacuumCleanerS1Status.html | 1 - .../robotVacuumCleanerS1WebhookContext.html | 1 - docs/types/robotVacuumCleanerServiceData.html | 1 - docs/types/stripLight.html | 1 - docs/types/stripLightServiceData.html | 1 - docs/types/stripLightStatus.html | 1 - docs/types/stripLightWebhookContext.html | 1 - docs/types/waterLeakDetector.html | 1 - docs/types/waterLeakDetectorServiceData.html | 1 - docs/types/waterLeakDetectorStatus.html | 1 - .../waterLeakDetectorWebhookContext.html | 1 - docs/variables/parameterChecker.html | 1 - docs/variables/urls.html | 2 +- eslint.config.js | 17 +- examples/README.md | 140 + examples/api-only.js | 66 + examples/basic-usage.js | 61 + examples/ble-only.js | 59 + examples/bot-password.js | 71 + examples/device-control.js | 108 + examples/event-handling.js | 76 + examples/typescript-usage.ts | 95 + package-lock.json | 10629 ++++++---------- package.json | 64 +- src/api.ts | 354 + src/ble.ts | 1115 ++ src/device.test.ts | 386 - src/device.ts | 4257 ------- src/devices/base.ts | 1017 ++ ...device-override-state-during-connection.ts | 74 + src/devices/index.ts | 70 + src/devices/sequence-device.ts | 120 + src/devices/wo-ai-hub.ts | 30 + src/devices/wo-air-purifier-pm25.ts | 152 + src/devices/wo-air-purifier-table.ts | 12 + src/devices/wo-air-purifier.ts | 167 + src/devices/wo-art-frame.ts | 12 + src/devices/wo-blind-tilt.ts | 193 + src/devices/wo-bulb.ts | 279 + src/devices/wo-candle-warmer-lamp.ts | 101 + src/devices/wo-ceiling-light.ts | 12 + src/devices/wo-circulator-fan.ts | 12 + src/devices/wo-climate-panel.ts | 12 + src/devices/wo-contact.ts | 40 + src/devices/wo-curtain.ts | 210 + src/devices/wo-floor-lamp.ts | 12 + src/devices/wo-garage-door-opener.ts | 12 + src/devices/wo-hand.ts | 245 + src/devices/wo-hub2.ts | 38 + src/devices/wo-hub3.ts | 12 + src/devices/wo-hubmini-matter.ts | 12 + src/devices/wo-humi.ts | 148 + src/devices/wo-humi2.ts | 14 + src/devices/wo-io-sensor-th.ts | 12 + src/devices/wo-keypad-vision-pro.ts | 21 + src/devices/wo-keypad-vision.ts | 12 + src/devices/wo-keypad.ts | 36 + src/devices/wo-leak.ts | 36 + src/devices/wo-lock-lite.ts | 11 + src/devices/wo-lock-pro-wifi.ts | 11 + src/devices/wo-lock-pro.ts | 150 + src/devices/wo-lock-vision-pro.ts | 11 + src/devices/wo-lock-vision.ts | 11 + src/devices/wo-lock.ts | 126 + src/devices/wo-pan-tilt-cam-plus-3k.ts | 94 + src/devices/wo-plug-mini-jp.ts | 12 + src/devices/wo-plug-mini-us.ts | 76 + src/devices/wo-presence.ts | 38 + src/devices/wo-relay-switch-1.ts | 143 + src/devices/wo-relay-switch-1pm.ts | 12 + src/devices/wo-relay-switch-2pm.ts | 42 + src/devices/wo-remote-with-screen.ts | 27 + src/devices/wo-remote.ts | 35 + src/devices/wo-rgbic-bulb.ts | 103 + src/devices/wo-rgbic-neon-wire-rope-light.ts | 124 + src/devices/wo-rgbicww-floor-lamp.ts | 12 + src/devices/wo-rgbicww-strip-light.ts | 12 + src/devices/wo-roller-shade.ts | 12 + src/devices/wo-sensor-th-plus.ts | 12 + src/devices/wo-sensor-th-pro-co2.ts | 12 + src/devices/wo-sensor-th-pro.ts | 12 + src/devices/wo-sensor-th.ts | 39 + src/devices/wo-smart-thermostat-radiator.ts | 12 + src/devices/wo-strip-light-3.ts | 12 + src/devices/wo-strip.ts | 12 + src/devices/wo-vacuum-k10-plus.ts | 11 + src/devices/wo-vacuum-k10-pro-combo.ts | 11 + src/devices/wo-vacuum-k10-pro.ts | 11 + src/devices/wo-vacuum-k11-plus.ts | 11 + src/devices/wo-vacuum-k20.ts | 11 + src/devices/wo-vacuum-s10.ts | 11 + src/devices/wo-vacuum-s20.ts | 11 + src/devices/wo-vacuum.ts | 162 + src/devices/wo-water-detector.ts | 25 + src/errors.ts | 132 + src/index.test.ts | 17 - src/index.ts | 180 +- src/parameter-checker.test.ts | 65 - src/parameter-checker.ts | 310 - src/settings.test.ts | 83 - src/settings.ts | 386 +- src/switchbot-ble.test.ts | 35 - src/switchbot-ble.ts | 352 - src/switchbot-openapi.test.ts | 46 - src/switchbot-openapi.ts | 393 - src/switchbot.ts | 631 + src/types/api.ts | 271 + src/types/ble-guards.test.ts | 67 - src/types/ble-guards.ts | 15 - src/types/ble.ts | 652 +- src/types/device.ts | 317 + src/types/index.ts | 166 + src/types/openapi.ts | 779 -- src/utils/bot-ble.ts | 136 + src/utils/circuit-breaker.ts | 243 + src/utils/connection-tracker.ts | 237 + src/utils/fallback-handler.ts | 202 + src/utils/index.ts | 386 + src/utils/relay-encryption.ts | 27 + src/utils/retry.ts | 210 + test/README.md | 18 + test/apis/ble-connection-cleanup.test.ts | 43 + test/apis/ble-notification-handling.test.ts | 92 + test/apis/ble-scanner-lifecycle.test.ts | 75 + test/apis/discovery.test.ts | 152 + test/apis/openapi-get-devices.test.ts | 17 + test/apis/switchbot-discover-api.test.ts | 31 + test/devices/airpurifier-encryption.test.ts | 49 + test/devices/airpurifier-preset-mode.test.ts | 38 + test/devices/airpurifier-status.test.ts | 88 + test/devices/art-frame.test.ts | 56 + test/devices/bot-password.test.ts | 112 + .../bulb-color-temperature-bounds.test.ts | 104 + test/devices/circulator-fan-variants.test.ts | 64 + test/devices/climate-panel-variants.test.ts | 52 + test/devices/curtain3-features.test.ts | 134 + test/devices/device-manager.test.ts | 108 + ...e-override-state-during-connection.test.ts | 84 + test/devices/floor-lamp.test.ts | 56 + test/devices/get-basic-info.test.ts | 86 + test/devices/hub3.test.ts | 55 + test/devices/hubmini-matter.test.ts | 55 + test/devices/humidifier-level-control.test.ts | 57 + test/devices/humidifier-mode-control.test.ts | 73 + test/devices/humidifier2-enhancement.test.ts | 67 + test/devices/keypad-vision-pro.test.ts | 55 + test/devices/keypad-vision.test.ts | 54 + test/devices/light-multi-command.test.ts | 137 + test/devices/lock-variants.test.ts | 88 + test/devices/passive-polling.test.ts | 75 + test/devices/plug-mini-eu.test.ts | 45 + .../devices/relay-2pm-channel-control.test.ts | 87 + test/devices/relay-encryption.test.ts | 51 + test/devices/relay-variants.test.ts | 66 + .../rgbic-bulb-segmented-control.test.ts | 195 + test/devices/rgbicww-floor-lamp.test.ts | 57 + test/devices/rgbicww-strip-light.test.ts | 52 + test/devices/roller-shade.test.ts | 52 + test/devices/sequence-device.test.ts | 123 + test/devices/set-mode.test.ts | 60 + test/devices/strip-encryption.test.ts | 49 + test/devices/strip-light-3.test.ts | 56 + .../thermostat-radiator-variants.test.ts | 64 + test/devices/vacuum-commands.test.ts | 103 + test/devices/vacuum-variants.test.ts | 84 + test/devices/wo-blind-tilt.test.ts | 79 + test/devices/wo-bulb.test.ts | 26 + test/devices/wo-hand.test.ts | 31 + test/devices/wo-lock.test.ts | 27 + test/devices/wo-pan-tilt-cam-plus-3k.test.ts | 77 + test/devices/wo-plug-mini-us.test.ts | 58 + test/devices/wo-relay-switch-1.test.ts | 60 + test/types/devices.test.ts | 156 + test/types/errors.test.ts | 153 + test/types/index-exports.test.ts | 31 + test/types/index-main-exports.test.ts | 14 + test/types/switchbot-ble-only.test.ts | 16 + test/utils/utils.retry.test.ts | 51 + test/utils/utils.test.ts | 142 + tmp-switchbot-scan.mjs | 79 + todo/todo.md | 15 + tsconfig.build.json | 17 + tsconfig.json | 23 +- vitest.config.ts | 11 + 542 files changed, 27719 insertions(+), 19539 deletions(-) delete mode 100644 .github/workflows/beta-release.yml create mode 100644 docs/classes/APIError.html create mode 100644 docs/classes/APINotAvailableError.html delete mode 100644 docs/classes/Advertising.html create mode 100644 docs/classes/BLEConnection.html create mode 100644 docs/classes/BLENotAvailableError.html create mode 100644 docs/classes/BLEScanner.html create mode 100644 docs/classes/CommandFailedError.html create mode 100644 docs/classes/ConnectionTimeoutError.html create mode 100644 docs/classes/DeviceManager.html create mode 100644 docs/classes/DeviceNotFoundError.html create mode 100644 docs/classes/DeviceOverrideStateDuringConnection.html create mode 100644 docs/classes/DiscoveryError.html delete mode 100644 docs/classes/ErrorUtils.html create mode 100644 docs/classes/OpenAPIClient.html delete mode 100644 docs/classes/ParameterChecker.html create mode 100644 docs/classes/SequenceDevice.html create mode 100644 docs/classes/SwitchBot.html delete mode 100644 docs/classes/SwitchBotBLE.html create mode 100644 docs/classes/SwitchBotError.html delete mode 100644 docs/classes/SwitchBotOpenAPI.html create mode 100644 docs/classes/ValidationError.html delete mode 100644 docs/classes/ValidationUtils.html create mode 100644 docs/classes/WoAIHub.html create mode 100644 docs/classes/WoAirPurifierPM25.html create mode 100644 docs/classes/WoArtFrame.html create mode 100644 docs/classes/WoCandleWarmerLamp.html create mode 100644 docs/classes/WoCirculatorFan.html create mode 100644 docs/classes/WoClimatePanel.html create mode 100644 docs/classes/WoFloorLamp.html create mode 100644 docs/classes/WoGarageDoorOpener.html create mode 100644 docs/classes/WoHubMiniMatter.html create mode 100644 docs/classes/WoKeypadVision.html create mode 100644 docs/classes/WoKeypadVisionPro.html create mode 100644 docs/classes/WoPanTiltCamPlus3K.html create mode 100644 docs/classes/WoRGBICBulb.html create mode 100644 docs/classes/WoRGBICNeonWireRopeLight.html create mode 100644 docs/classes/WoRGBICWWFloorLamp.html create mode 100644 docs/classes/WoRGBICWWStripLight.html create mode 100644 docs/classes/WoRelaySwitch2PM.html create mode 100644 docs/classes/WoRemoteWithScreen.html create mode 100644 docs/classes/WoRollerShade.html create mode 100644 docs/classes/WoSmartLockLite.html create mode 100644 docs/classes/WoSmartLockProWiFi.html create mode 100644 docs/classes/WoSmartLockVision.html create mode 100644 docs/classes/WoSmartLockVisionPro.html create mode 100644 docs/classes/WoSmartThermostatRadiator.html create mode 100644 docs/classes/WoStripLight3.html create mode 100644 docs/classes/WoVacuum.html create mode 100644 docs/classes/WoVacuumK10Plus.html create mode 100644 docs/classes/WoVacuumK10Pro.html create mode 100644 docs/classes/WoVacuumK10ProCombo.html create mode 100644 docs/classes/WoVacuumK11Plus.html create mode 100644 docs/classes/WoVacuumK20.html create mode 100644 docs/classes/WoVacuumS10.html create mode 100644 docs/classes/WoVacuumS20.html create mode 100644 docs/classes/WoWaterDetector.html delete mode 100644 docs/enums/SwitchBotBLEModelFriendlyName.html delete mode 100644 docs/enums/SwitchBotModel.html create mode 100644 docs/interfaces/APICommandRequest.html create mode 100644 docs/interfaces/APICommandResponse.html create mode 100644 docs/interfaces/APIDevice.html create mode 100644 docs/interfaces/APIDeviceStatus.html create mode 100644 docs/interfaces/APIErrorResponse.html create mode 100644 docs/interfaces/APIResponse.html delete mode 100644 docs/interfaces/AdvertisementData.html create mode 100644 docs/interfaces/AirPurifierCommands.html create mode 100644 docs/interfaces/AirPurifierServiceData.html create mode 100644 docs/interfaces/AirPurifierStatus.html create mode 100644 docs/interfaces/BLEAdvertisement.html create mode 100644 docs/interfaces/BLEScanOptions.html create mode 100644 docs/interfaces/BLEServiceData.html create mode 100644 docs/interfaces/BlindTiltCommands.html create mode 100644 docs/interfaces/BlindTiltServiceData.html create mode 100644 docs/interfaces/BlindTiltStatus.html create mode 100644 docs/interfaces/BotCommands.html create mode 100644 docs/interfaces/BotServiceData.html create mode 100644 docs/interfaces/BotStatus.html create mode 100644 docs/interfaces/BulbCommands.html create mode 100644 docs/interfaces/BulbServiceData.html create mode 100644 docs/interfaces/BulbStatus.html create mode 100644 docs/interfaces/CeilingLightCommands.html create mode 100644 docs/interfaces/CeilingLightServiceData.html create mode 100644 docs/interfaces/CeilingLightStatus.html delete mode 100644 docs/interfaces/Chars.html delete mode 100644 docs/interfaces/ColorLightServiceDataBase.html create mode 100644 docs/interfaces/CommandResult.html create mode 100644 docs/interfaces/ContactServiceData.html create mode 100644 docs/interfaces/ContactStatus.html create mode 100644 docs/interfaces/CurtainCommands.html create mode 100644 docs/interfaces/CurtainExtendedInfo.html create mode 100644 docs/interfaces/CurtainServiceData.html create mode 100644 docs/interfaces/CurtainStatus.html create mode 100644 docs/interfaces/DeviceInfo.html create mode 100644 docs/interfaces/DeviceListResponse.html create mode 100644 docs/interfaces/DiscoveryOptions.html delete mode 100644 docs/interfaces/ErrorObject.html create mode 100644 docs/interfaces/HubServiceData.html create mode 100644 docs/interfaces/HubStatus.html create mode 100644 docs/interfaces/HumidifierCommands.html create mode 100644 docs/interfaces/HumidifierServiceData.html create mode 100644 docs/interfaces/HumidifierStatus.html create mode 100644 docs/interfaces/KeypadStatus.html create mode 100644 docs/interfaces/LeakServiceData.html create mode 100644 docs/interfaces/LeakStatus.html delete mode 100644 docs/interfaces/LockBaseServiceData.html create mode 100644 docs/interfaces/LockCommands.html create mode 100644 docs/interfaces/LockServiceData.html create mode 100644 docs/interfaces/LockStatus.html create mode 100644 docs/interfaces/MeterServiceData.html create mode 100644 docs/interfaces/MeterStatus.html create mode 100644 docs/interfaces/MotionServiceData.html create mode 100644 docs/interfaces/MotionStatus.html delete mode 100644 docs/interfaces/NobleTypes.html delete mode 100644 docs/interfaces/Params.html create mode 100644 docs/interfaces/PlugCommands.html delete mode 100644 docs/interfaces/PlugMiniServiceDataBase.html create mode 100644 docs/interfaces/PlugServiceData.html create mode 100644 docs/interfaces/PlugStatus.html create mode 100644 docs/interfaces/PresenceServiceData.html create mode 100644 docs/interfaces/PresenceStatus.html delete mode 100644 docs/interfaces/PushRequest.html delete mode 100644 docs/interfaces/PushResponseBody.html create mode 100644 docs/interfaces/RelaySwitchCommands.html create mode 100644 docs/interfaces/RelaySwitchServiceData.html create mode 100644 docs/interfaces/RelaySwitchStatus.html create mode 100644 docs/interfaces/RemoteStatus.html delete mode 100644 docs/interfaces/Rule.html create mode 100644 docs/interfaces/SceneListResponse.html delete mode 100644 docs/interfaces/ServiceData.html create mode 100644 docs/interfaces/StripCommands.html create mode 100644 docs/interfaces/StripServiceData.html create mode 100644 docs/interfaces/StripStatus.html delete mode 100644 docs/interfaces/SwitchBotBLEDevice.html create mode 100644 docs/interfaces/SwitchBotConfig.html delete mode 100644 docs/interfaces/SwitchBotScanner.html delete mode 100644 docs/interfaces/TemperatureServiceDataBase.html create mode 100644 docs/interfaces/VacuumCommands.html create mode 100644 docs/interfaces/VacuumStatus.html create mode 100644 docs/interfaces/WebhookConfig.html delete mode 100644 docs/interfaces/WebhookDetail.html create mode 100644 docs/interfaces/WebhookDetails.html create mode 100644 docs/interfaces/WebhookQueryResponse.html create mode 100644 docs/interfaces/WebhookSetupResponse.html delete mode 100644 docs/interfaces/ad.html delete mode 100644 docs/interfaces/body.html delete mode 100644 docs/interfaces/bodyChange.html delete mode 100644 docs/interfaces/deleteWebhookResponse.html delete mode 100644 docs/interfaces/device.html delete mode 100644 docs/interfaces/deviceList.html delete mode 100644 docs/interfaces/deviceStatusRequest.html delete mode 100644 docs/interfaces/deviceWebhook.html delete mode 100644 docs/interfaces/deviceWebhookContext.html delete mode 100644 docs/interfaces/devices.html delete mode 100644 docs/interfaces/infraredRemoteList.html delete mode 100644 docs/interfaces/irdevice.html delete mode 100644 docs/interfaces/pushResponse.html delete mode 100644 docs/interfaces/queryWebhookResponse.html delete mode 100644 docs/interfaces/setupWebhookResponse.html delete mode 100644 docs/interfaces/updateWebhookResponse.html delete mode 100644 docs/interfaces/webhookRequest.html delete mode 100644 docs/types/BLEDeviceServiceData.html delete mode 100644 docs/types/CommandType.html create mode 100644 docs/types/ConnectionType.html delete mode 100644 docs/types/MacAddress.html create mode 100644 docs/types/PhysicalDeviceType.html create mode 100644 docs/types/VirtualDeviceType.html delete mode 100644 docs/types/airPurifier.html delete mode 100644 docs/types/airPurifierPM25WebhookContext.html delete mode 100644 docs/types/airPurifierServiceData.html delete mode 100644 docs/types/airPurifierStatus.html delete mode 100644 docs/types/airPurifierTable.html delete mode 100644 docs/types/airPurifierTablePM25WebhookContext.html delete mode 100644 docs/types/airPurifierTableServiceData.html delete mode 100644 docs/types/airPurifierTableStatus.html delete mode 100644 docs/types/airPurifierTableVOC.html delete mode 100644 docs/types/airPurifierTableVOCStatus.html delete mode 100644 docs/types/airPurifierTableVOCWebhookContext.html delete mode 100644 docs/types/airPurifierTableWebhookContext.html delete mode 100644 docs/types/airPurifierVOC.html delete mode 100644 docs/types/airPurifierVOCStatus.html delete mode 100644 docs/types/airPurifierVOCWebhookContext.html delete mode 100644 docs/types/airPurifierWebhookContext.html delete mode 100644 docs/types/batteryCirculatorFan.html delete mode 100644 docs/types/batteryCirculatorFanServiceData.html delete mode 100644 docs/types/batteryCirculatorFanStatus.html delete mode 100644 docs/types/batteryCirculatorFanWebhookContext.html delete mode 100644 docs/types/blindTilt.html delete mode 100644 docs/types/blindTiltServiceData.html delete mode 100644 docs/types/blindTiltStatus.html delete mode 100644 docs/types/blindTiltWebhookContext.html delete mode 100644 docs/types/bot.html delete mode 100644 docs/types/botServiceData.html delete mode 100644 docs/types/botStatus.html delete mode 100644 docs/types/botWebhookContext.html delete mode 100644 docs/types/ceilingLight.html delete mode 100644 docs/types/ceilingLightPro.html delete mode 100644 docs/types/ceilingLightProServiceData.html delete mode 100644 docs/types/ceilingLightProStatus.html delete mode 100644 docs/types/ceilingLightProWebhookContext.html delete mode 100644 docs/types/ceilingLightServiceData.html delete mode 100644 docs/types/ceilingLightStatus.html delete mode 100644 docs/types/ceilingLightWebhookContext.html delete mode 100644 docs/types/circulatorFanStatus.html delete mode 100644 docs/types/circulatorFanWebhookContext.html delete mode 100644 docs/types/colorBulb.html delete mode 100644 docs/types/colorBulbServiceData.html delete mode 100644 docs/types/colorBulbStatus.html delete mode 100644 docs/types/colorBulbWebhookContext.html delete mode 100644 docs/types/contactSensor.html delete mode 100644 docs/types/contactSensorServiceData.html delete mode 100644 docs/types/contactSensorStatus.html delete mode 100644 docs/types/contactSensorWebhookContext.html delete mode 100644 docs/types/curtain.html delete mode 100644 docs/types/curtain3.html delete mode 100644 docs/types/curtain3ServiceData.html delete mode 100644 docs/types/curtain3WebhookContext.html delete mode 100644 docs/types/curtainServiceData.html delete mode 100644 docs/types/curtainStatus.html delete mode 100644 docs/types/curtainWebhookContext.html delete mode 100644 docs/types/floorCleaningRobotS10.html delete mode 100644 docs/types/floorCleaningRobotS10Status.html delete mode 100644 docs/types/floorCleaningRobotS10WebhookContext.html delete mode 100644 docs/types/hub2.html delete mode 100644 docs/types/hub2ServiceData.html delete mode 100644 docs/types/hub2Status.html delete mode 100644 docs/types/hub2WebhookContext.html delete mode 100644 docs/types/hub3ServiceData.html delete mode 100644 docs/types/humidifier.html delete mode 100644 docs/types/humidifier2ServiceData.html delete mode 100644 docs/types/humidifier2Status.html delete mode 100644 docs/types/humidifier2WebhookContext.html delete mode 100644 docs/types/humidifierServiceData.html delete mode 100644 docs/types/humidifierStatus.html delete mode 100644 docs/types/humidifierWebhookContext.html delete mode 100644 docs/types/indoorCam.html delete mode 100644 docs/types/indoorCameraWebhookContext.html delete mode 100644 docs/types/keypad.html delete mode 100644 docs/types/keypadDetectorServiceData.html delete mode 100644 docs/types/keypadTouch.html delete mode 100644 docs/types/keypadTouchWebhookContext.html delete mode 100644 docs/types/keypadWebhookContext.html delete mode 100644 docs/types/lock.html delete mode 100644 docs/types/lockPro.html delete mode 100644 docs/types/lockProServiceData.html delete mode 100644 docs/types/lockProStatus.html delete mode 100644 docs/types/lockProWebhookContext.html delete mode 100644 docs/types/lockServiceData.html delete mode 100644 docs/types/lockStatus.html delete mode 100644 docs/types/lockWebhookContext.html delete mode 100644 docs/types/meter.html delete mode 100644 docs/types/meterPlus.html delete mode 100644 docs/types/meterPlusServiceData.html delete mode 100644 docs/types/meterPlusStatus.html delete mode 100644 docs/types/meterPlusWebhookContext.html delete mode 100644 docs/types/meterPro.html delete mode 100644 docs/types/meterProCO2ServiceData.html delete mode 100644 docs/types/meterProCO2Status.html delete mode 100644 docs/types/meterProCO2WebhookContext.html delete mode 100644 docs/types/meterProServiceData.html delete mode 100644 docs/types/meterProStatus.html delete mode 100644 docs/types/meterProWebhookContext.html delete mode 100644 docs/types/meterServiceData.html delete mode 100644 docs/types/meterStatus.html delete mode 100644 docs/types/meterWebhookContext.html delete mode 100644 docs/types/motionSensor.html delete mode 100644 docs/types/motionSensorServiceData.html delete mode 100644 docs/types/motionSensorStatus.html delete mode 100644 docs/types/motionSensorWebhookContext.html delete mode 100644 docs/types/onadvertisement.html delete mode 100644 docs/types/ondiscover.html delete mode 100644 docs/types/outdoorMeter.html delete mode 100644 docs/types/outdoorMeterServiceData.html delete mode 100644 docs/types/outdoorMeterStatus.html delete mode 100644 docs/types/outdoorMeterWebhookContext.html delete mode 100644 docs/types/panTiltCamWebhookContext.html delete mode 100644 docs/types/pantiltCam.html delete mode 100644 docs/types/pantiltCam2k.html delete mode 100644 docs/types/plug.html delete mode 100644 docs/types/plugMini.html delete mode 100644 docs/types/plugMiniJPServiceData.html delete mode 100644 docs/types/plugMiniJPWebhookContext.html delete mode 100644 docs/types/plugMiniStatus.html delete mode 100644 docs/types/plugMiniUSServiceData.html delete mode 100644 docs/types/plugMiniUSWebhookContext.html delete mode 100644 docs/types/plugStatus.html delete mode 100644 docs/types/plugWebhookContext.html delete mode 100644 docs/types/presenceSensor.html delete mode 100644 docs/types/presenceSensorServiceData.html delete mode 100644 docs/types/presenceSensorStatus.html delete mode 100644 docs/types/presenceSensorWebhookContext.html delete mode 100644 docs/types/relaySwitch1Context.html delete mode 100644 docs/types/relaySwitch1PMContext.html delete mode 100644 docs/types/relaySwitch1PMServiceData.html delete mode 100644 docs/types/relaySwitch1PMStatus.html delete mode 100644 docs/types/relaySwitch1ServiceData.html delete mode 100644 docs/types/relaySwitch1Status.html delete mode 100644 docs/types/remote.html delete mode 100644 docs/types/remoteServiceData.html delete mode 100644 docs/types/robotVacuumCleanerS1.html delete mode 100644 docs/types/robotVacuumCleanerS1Plus.html delete mode 100644 docs/types/robotVacuumCleanerS1PlusStatus.html delete mode 100644 docs/types/robotVacuumCleanerS1PlusWebhookContext.html delete mode 100644 docs/types/robotVacuumCleanerS1Status.html delete mode 100644 docs/types/robotVacuumCleanerS1WebhookContext.html delete mode 100644 docs/types/robotVacuumCleanerServiceData.html delete mode 100644 docs/types/stripLight.html delete mode 100644 docs/types/stripLightServiceData.html delete mode 100644 docs/types/stripLightStatus.html delete mode 100644 docs/types/stripLightWebhookContext.html delete mode 100644 docs/types/waterLeakDetector.html delete mode 100644 docs/types/waterLeakDetectorServiceData.html delete mode 100644 docs/types/waterLeakDetectorStatus.html delete mode 100644 docs/types/waterLeakDetectorWebhookContext.html delete mode 100644 docs/variables/parameterChecker.html create mode 100644 examples/README.md create mode 100644 examples/api-only.js create mode 100644 examples/basic-usage.js create mode 100644 examples/ble-only.js create mode 100644 examples/bot-password.js create mode 100644 examples/device-control.js create mode 100644 examples/event-handling.js create mode 100644 examples/typescript-usage.ts create mode 100644 src/api.ts create mode 100644 src/ble.ts delete mode 100644 src/device.test.ts delete mode 100644 src/device.ts create mode 100644 src/devices/base.ts create mode 100644 src/devices/device-override-state-during-connection.ts create mode 100644 src/devices/index.ts create mode 100644 src/devices/sequence-device.ts create mode 100644 src/devices/wo-ai-hub.ts create mode 100644 src/devices/wo-air-purifier-pm25.ts create mode 100644 src/devices/wo-air-purifier-table.ts create mode 100644 src/devices/wo-air-purifier.ts create mode 100644 src/devices/wo-art-frame.ts create mode 100644 src/devices/wo-blind-tilt.ts create mode 100644 src/devices/wo-bulb.ts create mode 100644 src/devices/wo-candle-warmer-lamp.ts create mode 100644 src/devices/wo-ceiling-light.ts create mode 100644 src/devices/wo-circulator-fan.ts create mode 100644 src/devices/wo-climate-panel.ts create mode 100644 src/devices/wo-contact.ts create mode 100644 src/devices/wo-curtain.ts create mode 100644 src/devices/wo-floor-lamp.ts create mode 100644 src/devices/wo-garage-door-opener.ts create mode 100644 src/devices/wo-hand.ts create mode 100644 src/devices/wo-hub2.ts create mode 100644 src/devices/wo-hub3.ts create mode 100644 src/devices/wo-hubmini-matter.ts create mode 100644 src/devices/wo-humi.ts create mode 100644 src/devices/wo-humi2.ts create mode 100644 src/devices/wo-io-sensor-th.ts create mode 100644 src/devices/wo-keypad-vision-pro.ts create mode 100644 src/devices/wo-keypad-vision.ts create mode 100644 src/devices/wo-keypad.ts create mode 100644 src/devices/wo-leak.ts create mode 100644 src/devices/wo-lock-lite.ts create mode 100644 src/devices/wo-lock-pro-wifi.ts create mode 100644 src/devices/wo-lock-pro.ts create mode 100644 src/devices/wo-lock-vision-pro.ts create mode 100644 src/devices/wo-lock-vision.ts create mode 100644 src/devices/wo-lock.ts create mode 100644 src/devices/wo-pan-tilt-cam-plus-3k.ts create mode 100644 src/devices/wo-plug-mini-jp.ts create mode 100644 src/devices/wo-plug-mini-us.ts create mode 100644 src/devices/wo-presence.ts create mode 100644 src/devices/wo-relay-switch-1.ts create mode 100644 src/devices/wo-relay-switch-1pm.ts create mode 100644 src/devices/wo-relay-switch-2pm.ts create mode 100644 src/devices/wo-remote-with-screen.ts create mode 100644 src/devices/wo-remote.ts create mode 100644 src/devices/wo-rgbic-bulb.ts create mode 100644 src/devices/wo-rgbic-neon-wire-rope-light.ts create mode 100644 src/devices/wo-rgbicww-floor-lamp.ts create mode 100644 src/devices/wo-rgbicww-strip-light.ts create mode 100644 src/devices/wo-roller-shade.ts create mode 100644 src/devices/wo-sensor-th-plus.ts create mode 100644 src/devices/wo-sensor-th-pro-co2.ts create mode 100644 src/devices/wo-sensor-th-pro.ts create mode 100644 src/devices/wo-sensor-th.ts create mode 100644 src/devices/wo-smart-thermostat-radiator.ts create mode 100644 src/devices/wo-strip-light-3.ts create mode 100644 src/devices/wo-strip.ts create mode 100644 src/devices/wo-vacuum-k10-plus.ts create mode 100644 src/devices/wo-vacuum-k10-pro-combo.ts create mode 100644 src/devices/wo-vacuum-k10-pro.ts create mode 100644 src/devices/wo-vacuum-k11-plus.ts create mode 100644 src/devices/wo-vacuum-k20.ts create mode 100644 src/devices/wo-vacuum-s10.ts create mode 100644 src/devices/wo-vacuum-s20.ts create mode 100644 src/devices/wo-vacuum.ts create mode 100644 src/devices/wo-water-detector.ts create mode 100644 src/errors.ts delete mode 100644 src/index.test.ts delete mode 100644 src/parameter-checker.test.ts delete mode 100644 src/parameter-checker.ts delete mode 100644 src/settings.test.ts delete mode 100644 src/switchbot-ble.test.ts delete mode 100644 src/switchbot-ble.ts delete mode 100644 src/switchbot-openapi.test.ts delete mode 100644 src/switchbot-openapi.ts create mode 100644 src/switchbot.ts create mode 100644 src/types/api.ts delete mode 100644 src/types/ble-guards.test.ts delete mode 100644 src/types/ble-guards.ts create mode 100644 src/types/device.ts create mode 100644 src/types/index.ts delete mode 100644 src/types/openapi.ts create mode 100644 src/utils/bot-ble.ts create mode 100644 src/utils/circuit-breaker.ts create mode 100644 src/utils/connection-tracker.ts create mode 100644 src/utils/fallback-handler.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/relay-encryption.ts create mode 100644 src/utils/retry.ts create mode 100644 test/README.md create mode 100644 test/apis/ble-connection-cleanup.test.ts create mode 100644 test/apis/ble-notification-handling.test.ts create mode 100644 test/apis/ble-scanner-lifecycle.test.ts create mode 100644 test/apis/discovery.test.ts create mode 100644 test/apis/openapi-get-devices.test.ts create mode 100644 test/apis/switchbot-discover-api.test.ts create mode 100644 test/devices/airpurifier-encryption.test.ts create mode 100644 test/devices/airpurifier-preset-mode.test.ts create mode 100644 test/devices/airpurifier-status.test.ts create mode 100644 test/devices/art-frame.test.ts create mode 100644 test/devices/bot-password.test.ts create mode 100644 test/devices/bulb-color-temperature-bounds.test.ts create mode 100644 test/devices/circulator-fan-variants.test.ts create mode 100644 test/devices/climate-panel-variants.test.ts create mode 100644 test/devices/curtain3-features.test.ts create mode 100644 test/devices/device-manager.test.ts create mode 100644 test/devices/device-override-state-during-connection.test.ts create mode 100644 test/devices/floor-lamp.test.ts create mode 100644 test/devices/get-basic-info.test.ts create mode 100644 test/devices/hub3.test.ts create mode 100644 test/devices/hubmini-matter.test.ts create mode 100644 test/devices/humidifier-level-control.test.ts create mode 100644 test/devices/humidifier-mode-control.test.ts create mode 100644 test/devices/humidifier2-enhancement.test.ts create mode 100644 test/devices/keypad-vision-pro.test.ts create mode 100644 test/devices/keypad-vision.test.ts create mode 100644 test/devices/light-multi-command.test.ts create mode 100644 test/devices/lock-variants.test.ts create mode 100644 test/devices/passive-polling.test.ts create mode 100644 test/devices/plug-mini-eu.test.ts create mode 100644 test/devices/relay-2pm-channel-control.test.ts create mode 100644 test/devices/relay-encryption.test.ts create mode 100644 test/devices/relay-variants.test.ts create mode 100644 test/devices/rgbic-bulb-segmented-control.test.ts create mode 100644 test/devices/rgbicww-floor-lamp.test.ts create mode 100644 test/devices/rgbicww-strip-light.test.ts create mode 100644 test/devices/roller-shade.test.ts create mode 100644 test/devices/sequence-device.test.ts create mode 100644 test/devices/set-mode.test.ts create mode 100644 test/devices/strip-encryption.test.ts create mode 100644 test/devices/strip-light-3.test.ts create mode 100644 test/devices/thermostat-radiator-variants.test.ts create mode 100644 test/devices/vacuum-commands.test.ts create mode 100644 test/devices/vacuum-variants.test.ts create mode 100644 test/devices/wo-blind-tilt.test.ts create mode 100644 test/devices/wo-bulb.test.ts create mode 100644 test/devices/wo-hand.test.ts create mode 100644 test/devices/wo-lock.test.ts create mode 100644 test/devices/wo-pan-tilt-cam-plus-3k.test.ts create mode 100644 test/devices/wo-plug-mini-us.test.ts create mode 100644 test/devices/wo-relay-switch-1.test.ts create mode 100644 test/types/devices.test.ts create mode 100644 test/types/errors.test.ts create mode 100644 test/types/index-exports.test.ts create mode 100644 test/types/index-main-exports.test.ts create mode 100644 test/types/switchbot-ble-only.test.ts create mode 100644 test/utils/utils.retry.test.ts create mode 100644 test/utils/utils.test.ts create mode 100644 tmp-switchbot-scan.mjs create mode 100644 todo/todo.md create mode 100644 tsconfig.build.json create mode 100644 vitest.config.ts diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 67e1454c..b90efb24 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -21,11 +21,25 @@ Always reference these instructions first and fallback to search or bash command - **Use lint:fix for automatic fixes**: `npm run lint:fix` to automatically fix ESLint issues ### Platform Requirements and Constraints -- **BLE functionality requires Linux-based OS only** (Raspbian, Ubuntu, etc.) -- **Windows and macOS are NOT supported** for BLE operations (use OpenAPI instead) +- **BLE functionality requires Linux or macOS** (Raspbian, Ubuntu, macOS, etc.) +- **Windows is NOT supported** for BLE operations (use OpenAPI instead) - **Node.js versions**: Must use ^20, ^22, or ^24 (currently using v20.19.4) - **ES Modules**: This project uses `"type": "module"` - always use ES import/export syntax +#### BLE Prerequisites + +**macOS:** +- Xcode installed +- Bluetooth permissions enabled for terminal app in System Preferences + +**Linux (Ubuntu/Debian/Raspbian):** +- Required packages: `sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev` +- For non-root access: `sudo setcap cap_net_raw+eip $(eval readlink -f \`which node\`)` +- Raspberry Pi: May need to disable pnat plugin in `/etc/bluetooth/main.conf` + +**Linux (Fedora/RPM):** +- Required packages: `sudo yum install bluez bluez-libs bluez-libs-devel` + ### Testing and Validation - **Basic functionality test**: After any changes to core classes, run this validation: ```javascript @@ -116,9 +130,9 @@ Always reference these instructions first and fallback to search or bash command ## Troubleshooting Common Issues ### BLE Not Working -- **Check OS**: BLE only works on Linux-based systems +- **Check OS**: BLE works on Linux and macOS systems only - **Install noble prerequisites**: May need additional system libraries for @stoprocent/noble -- **Use OpenAPI instead**: For Windows/macOS development, use SwitchBotOpenAPI class +- **Use OpenAPI instead**: For Windows development, use SwitchBotOpenAPI class ### Build Failures - **Check Node.js version**: Must be ^20, ^22, or ^24 @@ -156,7 +170,7 @@ npm run watch # Build and link for development - **Type definitions**: All device status and response types ### Dependencies Summary -- **@stoprocent/noble**: BLE functionality (Linux only) +- **@stoprocent/noble**: BLE functionality (Linux/macOS) - **undici**: HTTP client for API requests - **async-mutex**: Concurrency control - **TypeScript**: Language and compilation diff --git a/.github/workflows/beta-release.yml b/.github/workflows/beta-release.yml deleted file mode 100644 index 54e1ba49..00000000 --- a/.github/workflows/beta-release.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Beta Release - -on: - push: - branches: [beta-*.*.*, beta] - workflow_dispatch: - -jobs: - build_and_test: - uses: homebridge/.github/.github/workflows/nodejs-build-and-test.yml@latest - with: - enable_coverage: false - secrets: - token: ${{ secrets.GITHUB_TOKEN }} - lint: - needs: build_and_test - uses: homebridge/.github/.github/workflows/eslint.yml@latest - - publish: - needs: lint - permissions: - id-token: write - uses: homebridge/.github/.github/workflows/npm-publish-esm.yml@latest - with: - tag: 'beta' - dynamically_adjust_version: true - npm_version_command: 'pre' - pre_id: 'beta' - secrets: - npm_auth_token: ${{ secrets.npm_token }} - - pre-release: - needs: publish - uses: homebridge/.github/.github/workflows/pre-release.yml@latest - with: - npm_version: ${{ needs.publish.outputs.NPM_VERSION }} - body: | - **Beta Release** - **Version**: v${{ needs.publish.outputs.NPM_VERSION }} - [How To Test Beta Releases](https://github.com/OpenWonderLabs/homebridge-air/wiki/Beta-Version) - - github-releases-to-discord: - name: Discord Webhooks - needs: [build_and_test,publish] - uses: homebridge/.github/.github/workflows/discord-webhooks.yml@latest - with: - title: "Node-SwitchBot Module Beta Release" - description: | - Version `v${{ needs.publish.outputs.NPM_VERSION }}` - url: "https://github.com/OpenWonderLabs/homebridge-air/releases/tag/v${{ needs.publish.outputs.NPM_VERSION }}" - secrets: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL_LATEST }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3741c9b3..227a8c12 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,30 +1,80 @@ -name: Unified Release +name: Release on: push: branches: - #- "alpha-*" - #- "beta-*" - - latest + - 'beta-*' + - 'beta' + - 'latest' workflow_dispatch: jobs: + # ─── BETA RELEASE (branches starting with "beta") ──────────────────────────── + + # 1️⃣ Build and test + build_and_test: + if: startsWith(github.ref_name, 'beta') + uses: homebridge/.github/.github/workflows/nodejs-build-and-test.yml@latest + with: + enable_coverage: false + secrets: + token: ${{ secrets.GITHUB_TOKEN }} + + # 2️⃣ Lint + lint: + if: startsWith(github.ref_name, 'beta') + needs: build_and_test + uses: homebridge/.github/.github/workflows/eslint.yml@latest + + # 3️⃣ Publish beta to NPM (OIDC — id-token required here and in the reusable workflow) + beta-publish: + if: startsWith(github.ref_name, 'beta') + needs: lint + permissions: + id-token: write + uses: homebridge/.github/.github/workflows/npm-publish-esm.yml@latest + with: + tag: 'beta' + dynamically_adjust_version: true + npm_version_command: 'pre' + pre_id: 'beta' + secrets: + npm_auth_token: ${{ secrets.npm_token }} + + # 4️⃣ Create GitHub pre-release + beta-pre-release: + if: startsWith(github.ref_name, 'beta') + needs: beta-publish + uses: homebridge/.github/.github/workflows/pre-release.yml@latest + with: + npm_version: ${{ needs.beta-publish.outputs.NPM_VERSION }} + body: | + **Beta Release** + **Version**: v${{ needs.beta-publish.outputs.NPM_VERSION }} + [How To Test Beta Releases](https://github.com/OpenWonderLabs/homebridge-switchbot/wiki/Beta-Version) + + + # ─── STABLE RELEASE (branch: "latest") ─────────────────────────────────────── + # 1️⃣ Determine release type, ESM status, and branch name determine-release-type: + if: github.ref_name == 'latest' uses: homebridge/.github/.github/workflows/determine-release-type.yml@latest with: ref_name: ${{ github.ref_name }} # 2️⃣ Update version and changelog using the scripts update-version: + if: github.ref_name == 'latest' needs: determine-release-type uses: homebridge/.github/.github/workflows/update-version.yml@latest with: release_type: ${{ needs.determine-release-type.outputs.release_type }} is_esm: ${{ needs.determine-release-type.outputs.is_esm == 'true' }} - # 3️⃣ Publish to NPM and create GitHub release + # 3️⃣ Publish to NPM and create GitHub release (OIDC — id-token required here and in the reusable workflow) publish-release: + if: github.ref_name == 'latest' needs: [determine-release-type, update-version] permissions: id-token: write @@ -39,17 +89,17 @@ jobs: # 4️⃣ Promote branch if this is a prerelease (alpha/beta) promote-branch: + if: ${{ github.ref_name == 'latest' && needs.determine-release-type.outputs.release_type != 'latest' && needs.determine-release-type.outputs.release_type != 'skip' }} needs: [determine-release-type, publish-release] - if: ${{ needs.determine-release-type.outputs.release_type != 'latest' && needs.determine-release-type.outputs.release_type != 'skip' }} uses: homebridge/.github/.github/workflows/promote-branch.yml@latest with: branch_name: ${{ needs.determine-release-type.outputs.branch_name }} release_type: ${{ needs.determine-release-type.outputs.release_type }} is_esm: ${{ needs.determine-release-type.outputs.is_esm == 'true' }} - # 5️⃣ Notify if any previous job fails + # 5️⃣ Notify if any stable-release job fails workflow-failure: - if: ${{ failure() }} + if: failure() needs: [determine-release-type, update-version, publish-release, promote-branch] uses: homebridge/.github/.github/workflows/report-failure.yml@latest with: @@ -57,15 +107,16 @@ jobs: job_name: ${{ github.job }} run_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - # 6️⃣ Post to Discord - github-releases-to-discord: - name: Discord Webhooks - needs: [determine-release-type, update-version, publish-release] + # 6️⃣ Post to Discord (Beta + Stable) + discord: + name: Release Notifications + if: ${{ always() && ((startsWith(github.ref_name, 'beta') && needs.beta-publish.result == 'success') || (github.ref_name == 'latest' && needs.publish-release.result == 'success')) }} + needs: [beta-publish, update-version, publish-release] uses: homebridge/.github/.github/workflows/discord-webhooks.yml@latest with: - title: "Node-SwitchBot Module Release" + title: ${{ startsWith(github.ref_name, 'beta') && 'SwitchBot-Node Beta Release' || 'SwitchBot-Node Release' }} description: | - Version `v${{ needs.update-version.outputs.version }}` - url: "https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v${{ needs.update-version.outputs.version }}" + Version `v${{ startsWith(github.ref_name, 'beta') && needs.beta-publish.outputs.NPM_VERSION || needs.update-version.outputs.version }}` + url: "https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v${{ startsWith(github.ref_name, 'beta') && needs.beta-publish.outputs.NPM_VERSION || needs.update-version.outputs.version }}" secrets: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL_LATEST }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c3b7181e..e7c5882a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -3,10 +3,10 @@ name: Stale workflow on: workflow_dispatch: schedule: - - cron: '45 11 * * *' + - cron: '45 7 * * *' jobs: stale: - uses: OpenWonderLabs/.github/.github/workflows/stale.yml@latest + uses: homebridge/.github/.github/workflows/stale.yml@latest secrets: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.npmignore b/.npmignore index c9960b3e..a80f214e 100644 --- a/.npmignore +++ b/.npmignore @@ -2,6 +2,14 @@ src +# v4.0.0 additions +test/ +examples/ +.dev-archive/ +vitest.config.ts +typedoc.json +eslint.config.js + # ------------- Defaults ------------- # eslint diff --git a/BLE.md b/BLE.md index b83f4c4a..bd063306 100644 --- a/BLE.md +++ b/BLE.md @@ -6,835 +6,325 @@ The `SwitchBot` class allows you to interact with SwitchBot devices using the Sw - [BLE (Bluetooth Low Energy)](#ble-bluetooth-low-energy) - [Supported OS](#supported-os) - - [Dependencies](#dependencies) - - [Importing and Setting Up](#importing-and-setting-up) - - [`SwitchBotBLE` Object](#switchbot-object) - - [`discover()` method](#discover-method) - - [`ondiscover` event handler](#ondiscover-event-handler) - - [`startScan()` method](#startscan-method) - - [`onadvertisement` event handler](#onadvertisement-event-handler) - - [`stopScan()` method](#stopscan-method) - - [`wait()` method](#wait-method) - - [`SwitchBotDevice` Object](#switchbotdevice-object) - - [Properties](#properties) - - [`getDeviceName()` method](#getdevicename-method) - - [`setDeviceName()` method](#setdevicename-method) - - [`connect()` method](#connect-method) - - [`disconnect()` method](#disconnect-method) - - [`onconnect` event handler](#onconnect-event-handler) - - [`ondisconnect` event handler](#ondisconnect-event-handler) - - [`WoHand` Object](#wohand-object) - - [`press()` method](#press-method) - - [`turnOn()` method](#turnon-method) - - [`turnOff()` method](#turnoff-method) - - [`down()` method](#down-method) - - [`up()` method](#up-method) - - [`WoCurtain` object](#wocurtain-object) - - [`open()` method](#open-method) - - [`close()` method](#close-method) - - [`pause()` method](#pause-method) - - [`runToPos()` method](#runtopos-method) - - [`WoPlugMini` object](#woplugmini-object) - - [`turnOn()` method](#turnon-method) - - [`turnOff()` method](#turnoff-method) - - [`toggle()` method](#toggle-method) - - [`WoSmartLock` object](#wosmartlock-object) - - [`lock()` method](#lock-method) - - [`unlock()` method](#unlock-method) - - [`unlock_no_unlatch()` method](#unlock_no_unlatch-method) - - [`info()` method](#info-method) - - [Advertisement data](#advertisement-data) - - [Bot (WoHand)](#bot-wohand) - - [Meter (WoSensorTH)](#meter-wosensorth) - - [Curtain (WoCurtain)](#curtain-wocurtain) - - [Contact (WoContact)](#contact-wocontact) - - [Motion (WoMotion)](#motion-womotion) - - [PlugMini (WoPlugMini)](#plugmini-woplugmini) - - [Supported Devices](#supported-devices) - - [Advertisement Data](#advertisement-data) - - [Control Device](#control-device) - - [Summary](#summary) - -## BLE (Bluetooth Low Energy) - -### Supported OS - -The node-switchbot supports only Linux-based OSes, such as Raspbian, Ubuntu, and so on. This module does not support Windows and macOS for now. (If [@stoprocent/noble](https://github.com/stoprocent/noble#readme) is installed properly, this module might work well on such OSes.) - -### Dependencies - -- [Node.js](https://nodejs.org/en/): ^20 -- [@stoprocent/noble](https://github.com/stoprocent/noble) - - Included as a dependency so no need to install manually however if for some reason your OS requires addtional libaries, see `@stoprocent/noble` [prerequisites](https://github.com/stoprocent/noble?tab=readme-ov-file#prerequisites), you will then need to reinstall `node-switchbot` or the package that you have `node-swtichbot` as a dependency. - -### Importing and Setting Up - -To use the `SwitchBotBLE` class in `node-switchbot`, you need to import it and create an instance. + # SwitchBot BLE Documentation -```typescript -import { SwitchBotBLE } from 'node-switchbot' - -// Example usage -const switchBotBLE = new SwitchBotBLE() - -try { - await switchBotBLE.startScan() -} catch (e: any) { - console.error(`Failed to start BLE scanning, Error: ${e.message ?? e}`) -} -``` - -### `SwitchBotBLE` Object - -The `SwitchBotBLE` constructor takes an argument optionally. It must be a hash object containing the properties as follows: - -| Property | Type | Required | Description | -| :------- | :---- | :------- | :-------------------------------------------------------------------------------------- | -| `noble` | Noble | option | a Noble object of the [`@stoprocent/noble`](https://github.com/stoprocent/noble) module | - -The node-switchbot module uses the [`@stoprocent/noble`](https://github.com/stoprocent/noble) module in order to interact with BLE devices. If you want to interact other BLE devices using the `@stoprocent/noble` module, you can create an `Noble` object by yourself, then pass it to this module. If you don't specify a `Noble` object to the `noble` property, this module automatically create a `Noble` object internally. - -The sample code below shows how to pass a `Noble` object to the `Switchbot` constructor. - -```Typescript -// Create a Noble object -const noble = require('@stoprocent/noble'); - -const switchBotBLE = new SwitchBotBLE({ 'noble': Noble }) -``` - -In the code snippet above, the variable `switchbot` is an `SwitchBotBLE` object. The `SwitchBotBLE` object has a lot of methods as described in sections below. - -#### `discover()` method - -The `discover` method finds devices. This method returns a `Promise` object. This method takes an argument which is a hash object containing parameters as follows: - -| Property | Type | Required | Description | -| :--------- | :------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `duration` | Integer | Optional | Duration for discovery process (msec). The default value is 5000 (msec). | -| `model` | String | Optional | `"H"`, `"T"` or `"c"`. If `"H"` is specified, this method will discover only Bots. If `"T"` is specified, this method will discover only Meters. If `"c"` is specified, this method will discover only Curtains. | -| `id` | String | Optional | If this value is set, this method will discover only a device whose ID is as same as this value. The ID is identical to the MAC address. This parameter is case-insensitive, and colons are ignored. | -| `quick` | Boolean | Optional | If this value is `true`, this method finishes the discovery process when the first device is found, then calls the `resolve()` function without waiting the specified `duration`. The default value is `false`. | - -In the code snippet below, no parameter is passed to the method: - -```Typescript -switchBotBLE.discover().then((device_list) => { - // Do something... -}).catch((error) => { - console.error(error); -}); -``` - -If no parameter is passed to the method as the code above, an `Array` object will be passed to the `resolve()` function in 5 seconds. The `Array` object contains [`SwitchbotDevice`](#SwitchbotDevice-object) objects representing the found devices. See the section "[`SwitchbotDevice`](#SwitchbotDevice-object) objects" for more details. - -If you want a quick response, you can set the `quick` property to `true`. - -```Typescript -switchBotBLE.discover({ - duration: 5000, - quick: true -}).then((device_list) => { - // Do something... -}).catch((error) => { - console.error(error); -}); -``` - -As the `quick` property is set to `true`, the `resolve()` function will be called immediately after a device is found regardless the value of the `duration` property. - -#### `ondiscover` event handler - -The `ondiscover` property on the [`Switchbot`](#Switchbot-object) object is an event handler called whenever a device is newly found in the discovery process. A [`SwitchbotDevice`](#SwitchbotDevice-object) object is passed to the callback function set to the `ondiscover` property. - -```Typescript -switchBotBLE.ondiscover = (device) => { - console.log(device.id + ' (' + device.modelName + ')'); -}; - -switchBotBLE.discover().then(() => { - console.log('The discovery process was finished.'); -}).catch((error) => { - console.error(error); -}); -``` - -The code snippet above will output the result as follows: - -``` -cb4eb903c96d (WoSensorTH) -c12e453e2008 (WoHand) -The discovery process was finished. -``` - -#### `startScan()` method - -The `startScan()` method starts to scan advertising packets coming from devices. This method takes an argument which is a hash object containing the parameters as follows: - -| Property | Type | Required | Description | -| :------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | String | Optional | `"H"`, `"T"`, `"c"`, `"g"` or `"j"`. If `"H"` is specified, this method will discover only Bots. If `"T"` is specified, this method will discover only Meters. If `"c"` is specified, this method will discover only Curtains. If `"g"` or `"j"` is specified, this method will discover only (US/JP) Plug Minis. | -| `id` | String | Optional | If this value is set, this method will discover only a device whose ID is as same as this value. The ID is identical to the MAC address. This value is case-insensitive, and colons are ignored. | - -Whenever a packet is received, the callback function set to the [`onadvertisement`](#Switchbot-onadvertisement-event-handler) property of the [`Switchbot`](#Switchbot-object) object will be called. When a packet is received, a hash object representing the packet will be passed to the callback function. - -```Typescript -// Set a callback function called when a packet is received -switchBotBLE.onadvertisement = (ad) => { - console.log(ad); -}; - -// Start to scan advertising packets -switchBotBLE.startScan({ - id: 'cb:4e:b9:03:c9:6d', -}).then(() => { - // Wait for 30 seconds - return switchBotBLE.wait(30000); -}).then(() => { - // Stop to scan - switchBotBLE.stopScan(); - process.exit(); -}).catch((error) => { - console.error(error); -}); -``` - -The code snippet above will output the result as follows: - -``` -{ - id: 'cb4eb903c96d', - address: 'cb:4e:b9:03:c9:6d', - rssi: -65, - serviceData: { - model: 'T', - modelName: 'WoSensorTH', - celsius: 25.8, - fahrenheit: 78.4, - fahrenheit_mode: false, - humidity: 43, - battery: 100 - } -} -... -``` + BLE support in `node-switchbot` is part of the v4 unified architecture. The primary API is the `SwitchBot` class, which can use BLE directly, OpenAPI directly, or both together with automatic fallback. -The `serviceData` property depends on the model of the device. See the section "[Advertisement data](#Advertisement-data)" for the details of the data format. + This document covers: -#### `onadvertisement` event handler + - BLE support and prerequisites on macOS and Linux + - BLE-first usage through the unified `SwitchBot` class + - Bot password protection over BLE + - Low-level BLE helpers for advanced use: `BLEScanner` and `BLEConnection` -If a callback function is set to the `onadvertisement` property, the callback function will be called whenever an advertising packet is received from a device during the scan is active (from the moment when the [`startScan()`](#startscan-method) method is called, to the moment when the [`stopScan()`](#Switchbot-stopScan-method) method is called). + ## v4 BLE Model -```typescript -switchBotBLE.onadvertisement = async (ad: any) => { - try { - this.bleEventHandler[ad.address]?.(ad.serviceData) - } catch (e: any) { - await this.errorLog(`Failed to handle BLE event, Error: ${e.message ?? e}`) - } -} -``` + In v4.0.0, BLE is no longer a separate top-level workflow that you have to adopt in isolation. Instead: -See the section "[`startScan()` method](#startscan-method)" for details. + - `SwitchBot` is the main public entry point + - BLE is used when `enableBLE: true` + - OpenAPI can be used as fallback when credentials are present + - Devices are accessed through `switchbot.devices` + - Per-device commands automatically choose the best available connection path -#### `stopScan()` method + ## Supported Platforms -The `stopScan()` method stops to scan advertising packets coming from devices. This method returns nothing. Note that this method is _not_ asynchronous but synchronous unlike the other methods. See the section "[`startScan()` method](#startscan-method)" for details. + BLE is supported on: -```typescript -try { - switchBotBLE.stopScan() - console.log('Stopped BLE scanning to close listening.') -} catch (e: any) { - console.error(`Failed to stop BLE scanning, Error: ${e.message ?? e}`) -} -``` - -#### `wait()` method + - macOS + - Linux, including Ubuntu, Debian, Raspbian, and similar distributions -The `wait()` method waits for the specified milliseconds. This method takes an integer representing the duration (millisecond). This method returns a `Promise` object. + BLE is not supported on Windows in this package. On Windows, use API-only mode through the unified `SwitchBot` class. -This method has nothing to do with Switchbot devices. It's just a utility method. See the section "[Quick Start](#Quick-Start)" for details of the usage of this method. - -```typescript -await switchBotBLE.wait(1000) -``` + ## Requirements -### `SwitchBotDevice` Object + - Node.js `^20 || ^22 || ^24` + - `@stoprocent/noble` is included as a dependency -The `SwitchbotDevice` object represents a Switchbot device (Bot, Meter, Curtain, Contact or Motion), which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + ## Prerequisites -Actually, the `SwitchbotDevice` object is a super class of the [`WoHand`](#SwitchbotDeviceWoHand-object) and `WoSensorTH` objects. The [`WoHand`](#SwitchbotDeviceWoHand-object) object represents a Bot, the `WoSensorTH` object represents a Meter. + ### macOS -You can use the properties and methods described in this section on Bot, Meter, Curtain, Contact and Motion. See the section "[`WoHand` object](#SwitchbotDeviceWoHand-object)" for the details of the functionalities available only on Bot. For now, `WoSensorTH` object has no additional functionality. + - Install Xcode from the App Store + - Allow Bluetooth access for your terminal application in System Settings or System Preferences -#### Properties + ### Linux (Ubuntu, Debian, Raspbian) -The `SwitchbotDevice` object supports the properties as follows: + Install required packages: -| Property | Type | Description | -| :---------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | String | ID of the device. (e.g., `"cb4eb903c96d"`) | -| `address` | String | MAC address of the device. Basically it is as same as the value of the `id` except that this value includes `:` in the string. (e.g., `"cb:4e:b9:03:c9:6d"`) | -| `model` | String | This value is `"H"` "Bot (WoHand)", `"T"` "Meter (WoSensorTH)", `"c"` "Curtain (WoCurtain)", `"d"` "Contact (WoContact)" or `"s"` "Motion (WoMotion)". | -| `modelName` | String | This value is `"WoHand"`, `"WoSensorTH"`, `WoCurtain`, `WoContect` or `WoMotion`. | -| `connectionState` | String | This value indicates the BLE connection state. `"connecting"`, `"connected"`, `"disconnecting"`, or `"disconnected"`. | -| `onconnect` | Function | See the section "[`onconnect` event handler](#SwitchbotDevice-onconnect-event-handler)" for details. | -| `ondisconnect` | Function | See the section "[`ondisconnect` event handler](#SwitchbotDevice-ondisconnect-event-handler)" for details. | - -#### `getDeviceName()` method - -The `getDeviceName()` method fetches the device name saved in the device. This method returns a `Promise` object. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -If the device name is fetched successfully, the device name will be passed to the `resolve()`. - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].getDeviceName(); - }) - .then((name) => { - console.log(name); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` - -The code above will output the result as follows: - -```Typescript -WoHand; -``` + ```bash + sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev + ``` -#### `setDeviceName()` method + For non-root access, also install `libcap2-bin` and grant raw socket capability to `node`: -The `setDeviceName()` method update the device name saved in the device with the name specified as the first argument. This method returns a `Promise` object. Nothing will be passed to the `resolve()` function. + ```bash + sudo apt-get install libcap2-bin + sudo setcap cap_net_raw+eip $(eval readlink -f `which node`) + ``` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + On Raspberry Pi, if BLE connections are unstable, you may need to disable the `pnat` plugin in `/etc/bluetooth/main.conf` and restart Bluetooth or reboot. -The character set of the device name saved in the device is UTF-8. The byte length of the name must be less than or equal to 20 bytes. If the name consists of only ASCII characters, up to 20 characters would be allowed. But if the name consists of multibyte characters, the upper limit of characters would be fewer than half. For example, Japanese characters could be saved at most 6 characters because most of Japanese characters consume 3 byte per each character. + ### Fedora and Other RPM-Based Linux -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].setDeviceName("Bot in kitchen"); - }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` + ```bash + sudo yum install bluez bluez-libs bluez-libs-devel + ``` -#### `connect()` method + For more platform details, see the `@stoprocent/noble` prerequisites documentation. -The `connect()` method establishes a connection with the device (i.e., pairing). This method returns a `Promise` object. If the device has already been connected, this method does nothing and calls the `resolve()` function immediately. + ## Unified BLE Usage -Most of the methods implemented in the `SwitchbotDevice` object automatically connect and disconnect the device. But this mechanism would be absolutely inefficient if you want to manipulate the device repeatedly in the short time. + ### BLE-Only Mode -The connection established using the `connect()` method is not disconnected automatically unless the [`disconnect()`](#SwitchbotDevice-disconnect-method) method is explicitly called. + Use BLE without OpenAPI credentials: -The code snippet below establishes a connection with the Bot using the `connect()` method, then puts the Bot's arm down, then waits for 5 seconds, then puts the arm down, finally disconnects the device using the [`disconnect()`](#SwitchbotDevice-disconnect-method) method: + ```typescript + import { LogLevel, SwitchBot } from 'node-switchbot' -```Typescript -let device = null; - -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - device = device_list[0]; - if (!device) { - console.log("No device was found."); - process.exit(); - } - console.log(device.modelName + " (" + device.address + ") was found."); - console.log("Connecting..."); - return device.connect(); + const switchbot = new SwitchBot({ + enableBLE: true, + enableFallback: false, + logLevel: LogLevel.INFO, }) - .then(() => { - console.log("Putting the arm down..."); - return device.down(); - }) - .then(() => { - console.log("Waiting for 5 seconds..."); - return switchBotBLE.wait(5000); - }) - .then(() => { - console.log("Putting the arm up..."); - return device.up(); - }) - .then(() => { - console.log("Disconnecting..."); - return device.disconnect(); - }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` -The result will be as follows: - -``` -WoHand (c1:2e:45:3e:20:08) was found. -Connecting... -Putting the arm down... -Waiting for 5 seconds... -Putting the arm up... -Disconnecting... -Done. -``` - -#### `disconnect()` method - -The `disconnect()` method disconnects the device. This method returns a `Promise` object. If the device has already been disconnected, this method does nothing and calls the `resolve()` function immediately. - -See the [previous section](#SwitchbotDevice-connect-method) for more details. - -#### `onconnect` event handler - -The `onconnect` event handler will be called when the connection with the device is established. Nothing will be passed to the handler. - -The code below calls the [`press()`](#SwitchbotDeviceWoHand-press-method) method, while callback functions are attached to the `onconnect` and `ondisconnect`. - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - const device = device_list[0]; - if (!device) { - console.log("No device was found."); - process.exit(); - } - console.log(device.modelName + " (" + device.address + ") was found."); - - // Set event handers - device.onconnect = () => { - console.log("Connected."); - }; - device.ondisconnect = () => { - console.log("Disconnected."); - }; - - console.log("Pressing the switch..."); - return device.press(); + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: false, + timeout: 10_000, }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` - -The code above will output the result as follows: - -``` -WoHand (c1:2e:45:3e:20:08) was found. -Pressing the switch... -Connected. -Disconnected. -Done. -``` - -Seeing the result, you would find the [`press()`](#SwitchbotDeviceWoHand-press-method) method automatically connects and disconnects the device. -#### `ondisconnect` event handler + console.log(`Found ${devices.length} BLE device(s)`) -The `ondisconnect` event handler will be called when the connection with the device is closed. Nothing will be passed to the handler. See the previous section "[`onconnect` event handler](#SwitchbotDevice-onconnect-event-handler)" for more details. - -### `WoHand` Object - -The `WoHand` object represents a Bot, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + const bot = switchbot.devices.get('YOUR_DEVICE_ID') + if (bot) { + await bot.press() + } -Actually, the `WoHand` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. + await switchbot.cleanup() + ``` -#### `press()` method + ### Hybrid BLE + API Mode -The `press()` method sends a press command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + Use BLE first, with automatic API fallback when needed: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ```typescript + import { LogLevel, SwitchBot } from 'node-switchbot' -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].press(); - }) - .then(() => { - console.log("Done."); + const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: true, + enableFallback: true, + enableConnectionIntelligence: true, + enableCircuitBreaker: true, + enableRetry: true, + logLevel: LogLevel.INFO, }) - .catch((error) => { - console.error(error); - }); -``` -When the Bot receives this command, the Bot's arm will be put down (stretched), then put up (retracted) in a few seconds. - -#### `turnOn()` method - -The `turnOn()` method sends a turn-on command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -When the Bot receives this command, the Bot's arm will be put down (stretched) or put up (retracted) depending on the mode setting. - -| Mode | Inverse the on/off direction | Physical position of the arm | -| :---------- | :--------------------------- | :------------------------------------ | -| Press mode | N/A | Down (stretched), then Up (retracted) | -| Switch mode | Disabled | Down (stretched) | -|   | Enabled | Up (retracted) | - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].turnOn(); - }) - .then(() => { - console.log("Done."); + await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10_000, }) - .catch((error) => { - console.error(error); - }); -``` - -#### `turnOff()` method - -The `turnOff()` method sends a turn-off command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. -When the Bot receives this command, the Bot's arm will be put down (stretched) or put up (retracted) depending on the mode setting. + const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') + if (curtain) { + await curtain.open() + const status = await curtain.getStatus() + console.log(status) + } -| Mode | Inverse the on/off direction | Physical position of the arm | -| :---------- | :--------------------------- | :------------------------------------ | -| Press mode | N/A | Down (stretched), then Up (retracted) | -| Switch mode | Disabled | Up (retracted) | -|   | Enabled | Down (stretched) | + await switchbot.cleanup() + ``` -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].turnOff(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ## Discovery Options -#### `down()` method + `switchbot.discover()` accepts the following v4 options: -The `down()` method sends a down command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + | Property | Type | Description | + | :-- | :-- | :-- | + | `scanBLE` | `boolean` | Enable BLE discovery for this call | + | `fetchAPI` | `boolean` | Fetch devices from OpenAPI for this call | + | `timeout` | `number` | Discovery timeout in milliseconds | + | `deviceId` | `string` | Filter by SwitchBot device ID | + | `mac` | `string` | Filter by MAC address | + | `deviceType` | `string` | Filter by device type | -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ## Device Access Pattern -When the Bot receives this command, the Bot's arm will be put down (stretched) regardless of the mode setting. + After discovery, use the device manager: -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].down(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ```typescript + const devices = switchbot.devices.list() + const bot = switchbot.devices.get('YOUR_DEVICE_ID') + const curtains = switchbot.devices.getByType('WoCurtain') + ``` -#### `up()` method + Common device helpers include: -The `up()` method sends an up command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + - `getInfo()` + - `getName()` + - `getDeviceType()` + - `getStatus()` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + Commands vary by device class. Examples: -When the Bot receives this command, the Bot's arm will be put up (retracted) regardless of the mode setting. + - Bot: `press()`, `turnOn()`, `turnOff()`, `handUp()`, `handDown()` + - Curtain: `open()`, `close()`, `pause()`, `setPosition()` + - Plug: `turnOn()`, `turnOff()`, `toggle()` -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].up(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ## Bot Password Protection -### `WoCurtain` Object + Bot (`WoHand`) devices support password-protected BLE commands in v4. -The `WoCurtain` object represents a Curtain, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + ### What It Adds -Actually, the `WoCurtain` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. + - Password validation for exactly 4 alphanumeric characters + - CRC32-based encrypted BLE command construction + - Automatic encrypted command execution when a password is configured + - Runtime helpers: `setPassword()`, `clearPassword()`, `hasPassword()` -#### `open()` method + ### Supported Commands -The `open()` method sends an open command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + When a password is set, these BLE Bot commands use the encrypted flow: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - `press()` + - `turnOn()` + - `turnOff()` + - `handUp()` + - `handDown()` -When the Curtain receives this command, the Curtain will open the curtain (0% position). If not calibrated, the Curtain does not move. + ### Example -The `open()` method receives an optional `mode` parameter. (See [`runToPos()`](#runtopos-method)) + ```typescript + import { LogLevel, SwitchBot, WoHand } from 'node-switchbot' -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].open(); - }) - .then(() => { - console.log("Done."); + const switchbot = new SwitchBot({ + enableBLE: true, + enableFallback: false, + logLevel: LogLevel.INFO, }) - .catch((error) => { - console.error(error); - }); -``` -#### `close()` method + await switchbot.discover({ scanBLE: true, fetchAPI: false }) -The `close()` method sends a close command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + const bot = switchbot.devices.get('YOUR_DEVICE_ID') as WoHand | undefined + if (bot) { + bot.setPassword('A1b2') -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -When the Curtain receives this command, the Curtain will close the curtain (100% position). If not calibrated, the Curtain does not move. - -The `close()` method receives an optional `mode` parameter. (See [`runToPos()`](#runtopos-method)) + if (bot.hasPassword()) { + await bot.press() + } -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].close(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + bot.clearPassword() + } -#### `pause()` method + await switchbot.cleanup() + ``` -The `pause()` method sends a pause command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + Notes: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - Passwords are stored in memory only + - The password must be configured again when your application starts + - Password-protected Bot commands require BLE and do not use OpenAPI fallback for the encrypted write path -When the Curtain receives this command, the Curtain will pause. + ## Reliability Features in BLE Workflows -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].pause(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + The v4 BLE path includes the resilience features introduced in the 4.0.0 release: -#### `runToPos()` method + - Automatic retry with exponential backoff and jitter + - Circuit breaker state management to avoid repeated failing connections + - Connection intelligence that can prefer the more reliable path over time + - Fallback hooks for custom logging, metrics, or alerting -The `runToPos()` method sends a position command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + These behaviors are primarily exposed through the unified `SwitchBot` and `SwitchBotDevice` flow rather than through manual low-level BLE orchestration. -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ## Low-Level BLE APIs -When the Curtain receives this command, the Curtain will run to the percentage position. If not calibrated, the Curtain does not move. + If you need raw scanning or connection control, v4 exports `BLEScanner` and `BLEConnection` directly. -The `open()` method sends an open command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + ### `BLEScanner` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + Use this for advertisement scanning and device discovery without going through `SwitchBot`. -When the Curtain receives this command, the Curtain will open the curtain (0% position). If not calibrated, the Curtain does not move. + ```typescript + import { BLEScanner } from 'node-switchbot' -| Property | Type | Required | Description | -| :-------- | :------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| `percent` | Integer | Required | The percentage of target position (`0-100`). (e.g., `50`) | -| `mode` | Integer | Optional | The running mode of Curtain.
`0x00` - Performance mode.
`0x01` - Silent mode.
`0xff` - Default. Unspecified, from Curtain's settings. | + const scanner = new BLEScanner() -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].runToPos(50); + scanner.on('discover', (advertisement) => { + console.log(advertisement) }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` - -### `WoPlugMini` Object - -The `WoPlugMini ` object represents a PlugMini, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. - -Actually, the `WoPlugMini ` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. - -#### `turnOn()` method - -The `turnOn()` method sends a turn-on command to the PlugMini. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is on (`true`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -#### `turnOff()` method - -The `turnOff()` method sends a turn-off command to the PlugMini. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is off (`false`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -#### `toggle()` method - -The `toggle()` method sends a toggle command to the PlugMini, toggling between the on and off state. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is on (`true`) or off (`false`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -### `WoSmartLock` Object - -The `WoSmartLock ` object represents a SmartLock, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. - -Actually, the `WoSmartLock ` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. - -#### `setKey()` method - -The `setKey()` method initialises the key information required for encrypted communication with the SmartLock - -This must be set before any control commands are sent to the device. To obtain the key information you will need to use an external tool - see [`pySwitchbot`](https://github.com/Danielhiversen/pySwitchbot/tree/master?tab=readme-ov-file#obtaining-locks-encryption-key) project for an example script. -Or, use [`switchbot-get-encryption-key`](https://www.npmjs.com/package/switchbot-get-encryption-key) npm script. - -| Property | Type | Description | -| :-------------- | :----- | :----------------------------------------------------------------------------------------------- | -| `keyId` | String | unique2 character ID for the key. (e.g., `"ff"`) returned from the SwitchBot api for your device | -| `encryptionKey` | String | the unique encryption key returned from the SwitchBot api for your device | -#### `lock()` method + await scanner.startScan({ duration: 10_000, active: true }) + ``` -The `lock()` method sends a lock command to the SmartLock. This method returns a `Promise` object. A `boolean` value indicating whether the SmartLock is locked (`true`), is passed to the `resolve()` method of the Promise. + Public methods: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - `startScan(options?)` + - `stopScan()` + - `getDiscoveredDevices()` + - `getDevice(mac, bleId?)` + - `waitForDevice(mac, timeoutMs?, bleId?)` + - `destroy()` -#### `unlock()` method + Events: -The `unlock()` method sends an unlock command to the SmartLock. This method returns a `Promise` object. A `boolean` value indicating whether the SmartLock is locked (`false`), is passed to the `resolve()` method of the Promise. + - `ready` + - `state-change` + - `scan-start` + - `scan-stop` + - `discover` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ### `BLEConnection` -#### `unlockNoUnlatch()` method + Use this for low-level connection, write, and notification handling. -The `unlockNoUnlatch()` method sends a partial unlock command to the SmartLock, unlocking without the full unlatch. + ```typescript + import { BLEConnection } from 'node-switchbot' + import { Buffer } from 'node:buffer' -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + const connection = new BLEConnection() -#### `info()` method + await connection.connect('AA:BB:CC:DD:EE:FF') + await connection.write('AA:BB:CC:DD:EE:FF', Buffer.from([0x57, 0x01, 0x00])) + const response = await connection.read('AA:BB:CC:DD:EE:FF') -The `info()` method retreieves state information from the SmartLock, This method returns a `Promise` object. An `object` value indicating with the state infor, is passed to the `resolve()` method of the Promise. + console.log(response) -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + await connection.disconnectAll() + ``` -### Advertisement Data + Key public methods: -After the [`startScan()`](#startscan-method) method is invoked, the [`onadvertisement`](#Switchbot-onadvertisement-event-handler) event handler will be called whenever an advertising packet comes from the switchbot devices. + - `connect(mac)` + - `write(mac, data)` + - `read(mac)` + - `disconnectAll()` + - `setPersistentConnectionTimeout(timeoutMs)` + - `setEncryption(mac, keyHex, ivHex, mode?)` + - `clearEncryption(mac)` -```Typescript -// Load the node-switchbot and get a `Switchbot` constructor object -import { SwitchBotBLE } from 'node-switchbot'; -// Create a `Switchbot` object -const switchBotBLE = new SwitchBotBLE(); - -(async () => { - // Start to monitor advertisement packets - await switchBotBLE.startScan(); - // Set an event handler - switchBotBLE.onadvertisement = (ad) => { - console.log(JSON.stringify(ad, null, ' ')); - }; - // Wait 10 seconds - await switchBotBLE.wait(10000); - // Stop to monitor - switchBotBLE.stopScan(); - process.exit(); -})(); -``` - -An object containing the properties as follows will be passed to the event handler: - -| Property | Type | Description | -| :------------ | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | String | ID of the device. (e.g., `"cb4eb903c96d"`) | -| `address` | String | MAC address of the device. Basically it is as same as the value of the `id` except that this value includes `:` in the string. (e.g., `"cb:4e:b9:03:c9:6d"`) | -| `rssi` | Integer | RSSI. (e.g., `-62`) | -| `serviceData` | Object | An object including the device-specific data. | - -The structures of the `serviceData` are described in the following sections. + ## BLE-Supported Device Families -#### Bot (WoHand) - -Example of the advertisement data: - -```json -{ - "id": "c12e453e2008", - "address": "c1:2e:45:3e:20:08", - "rssi": -61, - "serviceData": { - "model": "H", - "modelName": "WoHand", - "mode": true, - "state": false, - "battery": 100 - } -} -``` - -Structure of the `serviceData`: + v4 BLE support includes, among others: -| Property | Type | Description | -| :---------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | String | This value is always `"H"`, which means "Bot (WoHand)". | -| `modelName` | String | This value is always `"WoHand"`, which means "Bot". | -| `mode` | Boolean | This indicates the mode setting. When the mode is "Switch mode", this value is `true`. When the mode is "Press mode", this value is `false`. | -| `state` | Boolean | This value indicates whether the switch status is ON or OFF. | -| `battery` | Integer | (**experimental**) This value indicates the battery level (`%`). | + - Bot + - Curtain and Roller Shade + - Blind Tilt + - Meter family + - Plug Mini family + - Lock family + - Humidifier family + - Bulb and light families + - Leak, contact, and presence sensors + - Relay switch family -The `mode` can be changed only using the official smartphone app. The node-switchbot does not support changing the mode because the BLE protocol is non-public. + Exact per-device behavior still depends on what the physical device exposes over BLE. -If the `mode` is `false`, which means the "Press mode" is selected, the `state` is always `false`. If the `mode` is `true`, which means the "Switch mode" is selected, the `state` represents the logical state (ON or OFF). Note that it does _not_ mean the physical arm position. The physical arm position depends on the setting "Inverse the on/off direction" on the official smartphone app. + ## Summary -| "Inverse the on/off direction" | Value of the `state` | Logical state | Physical arm position | -| :----------------------------- | :------------------- | :------------ | :-------------------- | -| disabled | `true` | OFF | Up (retracted) | -|   | `false` | ON | Down (stretched) | + Use `SwitchBot` for almost all v4 BLE workflows. Reach for `BLEScanner` and `BLEConnection` only when you need direct advertisement scanning or manual low-level BLE control. | enabled | `true` | OFF | Down (stretched) | |   | `false` | ON | Up (retracted) | diff --git a/CHANGELOG.md b/CHANGELOG.md index bad52c5c..fa79e56d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,1327 +2,138 @@ All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/) -## [3.6.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.5...v3.6.6) (2026-02-25) - - -### Bug Fixes - -* sync package-lock.json with @stoprocent/noble@^2.3.14 ([#324](https://github.com/OpenWonderLabs/node-switchbot/issues/324)) ([0670987](https://github.com/OpenWonderLabs/node-switchbot/commit/06709876ab1bb4adc244507863f1b25b786b87f2)) - - -### Features - -* Add Plug Mini (EU) support ([#325](https://github.com/OpenWonderLabs/node-switchbot/issues/325)) ([1eb8d2e](https://github.com/OpenWonderLabs/node-switchbot/commit/1eb8d2e572e211482105c2563a736bdfabeb50be)) - - - -## [3.6.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.4...v3.6.5) (2026-02-19) - - - -## [3.6.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4) (2026-02-18) - - - -## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.1...v3.6.3) (2026-02-05) - - - -## [3.5.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.0...v3.5.1) (2025-07-25) - - - -# [3.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.9...v3.5.0) (2025-03-05) - - - -## [3.4.9](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.8...v3.4.9) (2025-01-24) - - - -## [3.4.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.7...v3.4.8) (2025-01-24) - - - -## [3.4.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.6...v3.4.7) (2025-01-24) - - - -## [3.4.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.5...v3.4.6) (2025-01-24) - - - -## [3.4.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.4...v3.4.5) (2025-01-24) - - - -## [3.4.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.3...v3.4.4) (2025-01-24) - - - -## [3.4.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.2...v3.4.3) (2024-12-22) - - - -## [3.4.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.1...v3.4.2) (2024-12-22) - - - -## [3.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.0...v3.4.1) (2024-11-28) - - - -# [3.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.3.0...v3.4.0) (2024-11-18) - - - -# [3.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.1...v3.3.0) (2024-11-02) - - - -## [3.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.0...v3.2.1) (2024-10-22) - - - -# [3.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.1...v3.2.0) (2024-10-22) - - - -## [3.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.0...v3.1.1) (2024-10-12) - - - -# [3.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.1...v3.1.0) (2024-10-12) - - - -## [3.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.0...v3.0.1) (2024-10-05) - - - -# [3.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.3.0...v3.0.0) (2024-10-05) - - - -# [2.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.2.0...v2.3.0) (2024-07-21) - - - -# [2.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.1...v2.2.0) (2024-06-26) - - - -## [2.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.0...v2.1.1) (2024-05-26) - - - -# [2.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0) (2024-05-14) - - - -## [2.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.2...v2.0.3) (2024-02-12) - - - -## [2.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.0...v2.0.2) (2024-02-10) - - - -# [2.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.1...v2.0.0) (2024-02-05) - - - -## [1.9.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.0...v1.9.1) (2023-11-21) - - - -# [1.9.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.2...v1.9.0) (2023-09-16) - - - -## [1.8.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.1...v1.8.2) (2023-07-26) - - - -## [1.8.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.0...v1.8.1) (2023-04-08) - - - -# [1.8.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0) (2023-01-29) - - - -## [1.7.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.2...v1.7.3) (2023-01-05) - - - -## [1.7.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.1...v1.7.2) (2022-12-26) - - - -## [1.7.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.0...v1.7.1) (2022-12-20) - - - -# [1.7.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.1...v1.7.0) (2022-12-08) - - - -## [1.6.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.0...v1.6.1) (2022-10-19) - - - -# [1.6.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.5.0...v1.6.0) (2022-10-18) - - - -# [1.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.1...v1.5.0) (2022-10-07) - - - -## [1.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.0...v1.4.1) (2022-08-27) - - - -# [1.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.3.0...v1.4.0) (2022-08-20) - - - -# [1.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.2.0...v1.3.0) (2022-06-25) - - - -# [1.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.2...v1.2.0) (2022-03-04) - - - -## [1.1.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.1...v1.1.2) (2021-11-13) - - - -## [1.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.0...v1.1.1) (2021-11-02) - - - -# [1.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.8...v1.1.0) (2021-10-27) - - - -## [1.0.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.7...v1.0.8) (2021-09-30) - - - -## [1.0.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.6...v1.0.7) (2021-09-25) - - - -## [1.0.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.5...v1.0.6) (2021-08-29) - - - -## [1.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.4...v1.0.5) (2021-08-04) - - - -## [1.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.3...v1.0.4) (2021-08-04) - - - -## [1.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.2...v1.0.3) (2021-07-30) - - - -## [1.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.1...v1.0.2) (2021-07-29) - - - -## [1.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.0...v1.0.1) (2021-07-29) - - - -# [1.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.2.0...v1.0.0) (2021-01-21) - - - -# [0.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.1.0...v0.2.0) (2020-11-05) - - - -# [0.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.5...v0.1.0) (2020-10-28) - - -### Bug Fixes - -* typo ([338044f](https://github.com/OpenWonderLabs/node-switchbot/commit/338044f3469788f76c189ba75be80518b1765107)) - - -### Features - -* Added support for running on the Raspberry Pi Zero W. ([017b244](https://github.com/OpenWonderLabs/node-switchbot/commit/017b244cfba178827b4a2504853cc013b7a6bc70)) - - - -## [0.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.4...v0.0.5) (2020-02-18) - - - -## [0.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.3...v0.0.4) (2020-02-10) - - - -## [0.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.2...v0.0.3) (2020-02-10) - - - -## [0.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2) (2019-11-20) - - - -## 0.0.1 (2019-11-20) - -## [3.6.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.4...v3.6.5) (2026-02-19) - - - -## [3.6.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4) (2026-02-18) - - - -## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.1...v3.6.3) (2026-02-05) - - - -## [3.5.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.0...v3.5.1) (2025-07-25) - - - -# [3.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.9...v3.5.0) (2025-03-05) - - - -## [3.4.9](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.8...v3.4.9) (2025-01-24) - - - -## [3.4.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.7...v3.4.8) (2025-01-24) - - - -## [3.4.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.6...v3.4.7) (2025-01-24) - - - -## [3.4.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.5...v3.4.6) (2025-01-24) - - - -## [3.4.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.4...v3.4.5) (2025-01-24) - - - -## [3.4.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.3...v3.4.4) (2025-01-24) - - - -## [3.4.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.2...v3.4.3) (2024-12-22) - - - -## [3.4.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.1...v3.4.2) (2024-12-22) - - - -## [3.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.0...v3.4.1) (2024-11-28) - - - -# [3.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.3.0...v3.4.0) (2024-11-18) - - - -# [3.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.1...v3.3.0) (2024-11-02) - - - -## [3.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.0...v3.2.1) (2024-10-22) - - - -# [3.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.1...v3.2.0) (2024-10-22) - - - -## [3.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.0...v3.1.1) (2024-10-12) - - - -# [3.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.1...v3.1.0) (2024-10-12) - - - -## [3.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.0...v3.0.1) (2024-10-05) - - - -# [3.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.3.0...v3.0.0) (2024-10-05) - - - -# [2.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.2.0...v2.3.0) (2024-07-21) - - - -# [2.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.1...v2.2.0) (2024-06-26) - - - -## [2.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.0...v2.1.1) (2024-05-26) - - - -# [2.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0) (2024-05-14) - - - -## [2.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.2...v2.0.3) (2024-02-12) - - - -## [2.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.0...v2.0.2) (2024-02-10) - - - -# [2.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.1...v2.0.0) (2024-02-05) - - - -## [1.9.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.0...v1.9.1) (2023-11-21) - - - -# [1.9.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.2...v1.9.0) (2023-09-16) - - - -## [1.8.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.1...v1.8.2) (2023-07-26) - - - -## [1.8.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.0...v1.8.1) (2023-04-08) - - - -# [1.8.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0) (2023-01-29) - - - -## [1.7.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.2...v1.7.3) (2023-01-05) - - - -## [1.7.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.1...v1.7.2) (2022-12-26) - - - -## [1.7.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.0...v1.7.1) (2022-12-20) - - - -# [1.7.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.1...v1.7.0) (2022-12-08) - - - -## [1.6.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.0...v1.6.1) (2022-10-19) - - - -# [1.6.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.5.0...v1.6.0) (2022-10-18) - - - -# [1.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.1...v1.5.0) (2022-10-07) - - - -## [1.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.0...v1.4.1) (2022-08-27) - - - -# [1.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.3.0...v1.4.0) (2022-08-20) - - - -# [1.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.2.0...v1.3.0) (2022-06-25) - - - -# [1.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.2...v1.2.0) (2022-03-04) - - - -## [1.1.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.1...v1.1.2) (2021-11-13) - - - -## [1.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.0...v1.1.1) (2021-11-02) - - - -# [1.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.8...v1.1.0) (2021-10-27) - - - -## [1.0.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.7...v1.0.8) (2021-09-30) - - - -## [1.0.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.6...v1.0.7) (2021-09-25) - - - -## [1.0.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.5...v1.0.6) (2021-08-29) - - - -## [1.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.4...v1.0.5) (2021-08-04) - - - -## [1.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.3...v1.0.4) (2021-08-04) - - - -## [1.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.2...v1.0.3) (2021-07-30) - - - -## [1.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.1...v1.0.2) (2021-07-29) - - - -## [1.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.0...v1.0.1) (2021-07-29) - - - -# [1.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.2.0...v1.0.0) (2021-01-21) - - - -# [0.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.1.0...v0.2.0) (2020-11-05) - - - -# [0.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.5...v0.1.0) (2020-10-28) - - -### Bug Fixes - -* typo ([338044f](https://github.com/OpenWonderLabs/node-switchbot/commit/338044f3469788f76c189ba75be80518b1765107)) - - -### Features - -* Added support for running on the Raspberry Pi Zero W. ([017b244](https://github.com/OpenWonderLabs/node-switchbot/commit/017b244cfba178827b4a2504853cc013b7a6bc70)) - - - -## [0.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.4...v0.0.5) (2020-02-18) - - - -## [0.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.3...v0.0.4) (2020-02-10) - - - -## [0.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.2...v0.0.3) (2020-02-10) - - - -## [0.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2) (2019-11-20) - - - -## 0.0.1 (2019-11-20) - -## [3.6.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.4...v3.6.5) (2026-02-19) - - - -## [3.6.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4) (2026-02-18) - - - -## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.1...v3.6.3) (2026-02-05) - - - -## [3.5.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.0...v3.5.1) (2025-07-25) - - - -# [3.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.9...v3.5.0) (2025-03-05) - - - -## [3.4.9](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.8...v3.4.9) (2025-01-24) - - - -## [3.4.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.7...v3.4.8) (2025-01-24) - - - -## [3.4.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.6...v3.4.7) (2025-01-24) - - - -## [3.4.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.5...v3.4.6) (2025-01-24) - - - -## [3.4.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.4...v3.4.5) (2025-01-24) - - - -## [3.4.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.3...v3.4.4) (2025-01-24) - - - -## [3.4.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.2...v3.4.3) (2024-12-22) - - - -## [3.4.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.1...v3.4.2) (2024-12-22) - - - -## [3.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.0...v3.4.1) (2024-11-28) - - - -# [3.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.3.0...v3.4.0) (2024-11-18) - - - -# [3.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.1...v3.3.0) (2024-11-02) - - - -## [3.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.0...v3.2.1) (2024-10-22) - - - -# [3.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.1...v3.2.0) (2024-10-22) - - - -## [3.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.0...v3.1.1) (2024-10-12) - - - -# [3.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.1...v3.1.0) (2024-10-12) - - - -## [3.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.0...v3.0.1) (2024-10-05) - - - -# [3.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.3.0...v3.0.0) (2024-10-05) - - - -# [2.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.2.0...v2.3.0) (2024-07-21) - - - -# [2.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.1...v2.2.0) (2024-06-26) - - - -## [2.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.0...v2.1.1) (2024-05-26) - - - -# [2.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0) (2024-05-14) - - - -## [2.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.2...v2.0.3) (2024-02-12) - - - -## [2.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.0...v2.0.2) (2024-02-10) - - - -# [2.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.1...v2.0.0) (2024-02-05) - - - -## [1.9.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.0...v1.9.1) (2023-11-21) - - - -# [1.9.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.2...v1.9.0) (2023-09-16) - - - -## [1.8.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.1...v1.8.2) (2023-07-26) - - - -## [1.8.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.0...v1.8.1) (2023-04-08) - - - -# [1.8.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0) (2023-01-29) - - - -## [1.7.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.2...v1.7.3) (2023-01-05) - - - -## [1.7.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.1...v1.7.2) (2022-12-26) - - - -## [1.7.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.0...v1.7.1) (2022-12-20) - - - -# [1.7.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.1...v1.7.0) (2022-12-08) - - - -## [1.6.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.0...v1.6.1) (2022-10-19) - - - -# [1.6.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.5.0...v1.6.0) (2022-10-18) - - - -# [1.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.1...v1.5.0) (2022-10-07) - - - -## [1.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.0...v1.4.1) (2022-08-27) - - - -# [1.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.3.0...v1.4.0) (2022-08-20) - - - -# [1.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.2.0...v1.3.0) (2022-06-25) - - - -# [1.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.2...v1.2.0) (2022-03-04) - - - -## [1.1.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.1...v1.1.2) (2021-11-13) - - - -## [1.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.0...v1.1.1) (2021-11-02) - - - -# [1.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.8...v1.1.0) (2021-10-27) - - - -## [1.0.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.7...v1.0.8) (2021-09-30) - - - -## [1.0.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.6...v1.0.7) (2021-09-25) - - - -## [1.0.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.5...v1.0.6) (2021-08-29) - - - -## [1.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.4...v1.0.5) (2021-08-04) - - - -## [1.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.3...v1.0.4) (2021-08-04) - - - -## [1.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.2...v1.0.3) (2021-07-30) - - - -## [1.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.1...v1.0.2) (2021-07-29) - - - -## [1.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.0...v1.0.1) (2021-07-29) - - - -# [1.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.2.0...v1.0.0) (2021-01-21) - - - -# [0.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.1.0...v0.2.0) (2020-11-05) - - - -# [0.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.5...v0.1.0) (2020-10-28) - - -### Bug Fixes - -* typo ([338044f](https://github.com/OpenWonderLabs/node-switchbot/commit/338044f3469788f76c189ba75be80518b1765107)) - - -### Features - -* Added support for running on the Raspberry Pi Zero W. ([017b244](https://github.com/OpenWonderLabs/node-switchbot/commit/017b244cfba178827b4a2504853cc013b7a6bc70)) - - - -## [0.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.4...v0.0.5) (2020-02-18) - - - -## [0.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.3...v0.0.4) (2020-02-10) - - - -## [0.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.2...v0.0.3) (2020-02-10) - - - -## [0.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2) (2019-11-20) - - - -## 0.0.1 (2019-11-20) - -## [3.6.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4) (2026-02-18) - - - -## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.1...v3.6.3) (2026-02-05) - - - -## [3.5.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.0...v3.5.1) (2025-07-25) - - - -# [3.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.9...v3.5.0) (2025-03-05) - - - -## [3.4.9](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.8...v3.4.9) (2025-01-24) - - - -## [3.4.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.7...v3.4.8) (2025-01-24) - - - -## [3.4.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.6...v3.4.7) (2025-01-24) - - - -## [3.4.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.5...v3.4.6) (2025-01-24) - - - -## [3.4.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.4...v3.4.5) (2025-01-24) - - - -## [3.4.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.3...v3.4.4) (2025-01-24) - - - -## [3.4.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.2...v3.4.3) (2024-12-22) - - - -## [3.4.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.1...v3.4.2) (2024-12-22) - - - -## [3.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.0...v3.4.1) (2024-11-28) - - - -# [3.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.3.0...v3.4.0) (2024-11-18) - - - -# [3.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.1...v3.3.0) (2024-11-02) - - - -## [3.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.0...v3.2.1) (2024-10-22) - - - -# [3.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.1...v3.2.0) (2024-10-22) - - - -## [3.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.0...v3.1.1) (2024-10-12) - - - -# [3.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.1...v3.1.0) (2024-10-12) - - - -## [3.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.0...v3.0.1) (2024-10-05) - - - -# [3.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.3.0...v3.0.0) (2024-10-05) - - - -# [2.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.2.0...v2.3.0) (2024-07-21) - - - -# [2.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.1...v2.2.0) (2024-06-26) - - - -## [2.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.0...v2.1.1) (2024-05-26) - - - -# [2.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0) (2024-05-14) - - - -## [2.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.2...v2.0.3) (2024-02-12) - - - -## [2.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.0...v2.0.2) (2024-02-10) - - - -# [2.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.1...v2.0.0) (2024-02-05) - - - -## [1.9.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.0...v1.9.1) (2023-11-21) - - - -# [1.9.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.2...v1.9.0) (2023-09-16) - - - -## [1.8.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.1...v1.8.2) (2023-07-26) - - - -## [1.8.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.0...v1.8.1) (2023-04-08) - - - -# [1.8.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0) (2023-01-29) - - - -## [1.7.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.2...v1.7.3) (2023-01-05) - - - -## [1.7.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.1...v1.7.2) (2022-12-26) - - - -## [1.7.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.0...v1.7.1) (2022-12-20) - - - -# [1.7.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.1...v1.7.0) (2022-12-08) - - - -## [1.6.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.0...v1.6.1) (2022-10-19) - +## [4.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.8...v4.0.0) (2026-04-10) +### ⚠ BREAKING CHANGES -# [1.6.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.5.0...v1.6.0) (2022-10-18) - - - -# [1.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.1...v1.5.0) (2022-10-07) - - - -## [1.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.0...v1.4.1) (2022-08-27) - - - -# [1.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.3.0...v1.4.0) (2022-08-20) - - - -# [1.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.2.0...v1.3.0) (2022-06-25) - - - -# [1.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.2...v1.2.0) (2022-03-04) - - - -## [1.1.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.1...v1.1.2) (2021-11-13) - - - -## [1.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.0...v1.1.1) (2021-11-02) - - - -# [1.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.8...v1.1.0) (2021-10-27) - - - -## [1.0.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.7...v1.0.8) (2021-09-30) - - - -## [1.0.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.6...v1.0.7) (2021-09-25) - - - -## [1.0.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.5...v1.0.6) (2021-08-29) - - - -## [1.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.4...v1.0.5) (2021-08-04) - - - -## [1.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.3...v1.0.4) (2021-08-04) - - - -## [1.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.2...v1.0.3) (2021-07-30) - - - -## [1.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.1...v1.0.2) (2021-07-29) - - - -## [1.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.0...v1.0.1) (2021-07-29) - - - -# [1.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.2.0...v1.0.0) (2021-01-21) - - - -# [0.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.1.0...v0.2.0) (2020-11-05) - - - -# [0.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.5...v0.1.0) (2020-10-28) - - -### Bug Fixes - -* typo ([338044f](https://github.com/OpenWonderLabs/node-switchbot/commit/338044f3469788f76c189ba75be80518b1765107)) - +* Complete rewrite with unified hybrid BLE/API architecture +* No backward compatibility with v3.x - migration required +* Single `SwitchBot` class replaces `SwitchBotBLE` and `SwitchBotOpenAPI` +* Device access via `switchbot.devices` manager pattern +* Full TypeScript rewrite with comprehensive type definitions ### Features -* Added support for running on the Raspberry Pi Zero W. ([017b244](https://github.com/OpenWonderLabs/node-switchbot/commit/017b244cfba178827b4a2504853cc013b7a6bc70)) - - - -## [0.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.4...v0.0.5) (2020-02-18) - - - -## [0.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.3...v0.0.4) (2020-02-10) - - - -## [0.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.2...v0.0.3) (2020-02-10) - - - -## [0.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2) (2019-11-20) - - - -## 0.0.1 (2019-11-20) - -## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.1...v3.6.3) (2026-02-05) - - - -## [3.5.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.5.0...v3.5.1) (2025-07-25) - - - -# [3.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.9...v3.5.0) (2025-03-05) - - - -## [3.4.9](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.8...v3.4.9) (2025-01-24) - - - -## [3.4.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.7...v3.4.8) (2025-01-24) - - - -## [3.4.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.6...v3.4.7) (2025-01-24) - - - -## [3.4.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.5...v3.4.6) (2025-01-24) - - - -## [3.4.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.4...v3.4.5) (2025-01-24) - - - -## [3.4.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.3...v3.4.4) (2025-01-24) - - - -## [3.4.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.2...v3.4.3) (2024-12-22) - - - -## [3.4.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.1...v3.4.2) (2024-12-22) - - - -## [3.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.4.0...v3.4.1) (2024-11-28) - - - -# [3.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.3.0...v3.4.0) (2024-11-18) - - - -# [3.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.1...v3.3.0) (2024-11-02) - - - -## [3.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.2.0...v3.2.1) (2024-10-22) - - - -# [3.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.1...v3.2.0) (2024-10-22) - - - -## [3.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.1.0...v3.1.1) (2024-10-12) - - - -# [3.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.1...v3.1.0) (2024-10-12) - - - -## [3.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.0.0...v3.0.1) (2024-10-05) - - - -# [3.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.3.0...v3.0.0) (2024-10-05) - - - -# [2.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.2.0...v2.3.0) (2024-07-21) - - - -# [2.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.1...v2.2.0) (2024-06-26) - - - -## [2.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.1.0...v2.1.1) (2024-05-26) - - - -# [2.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0) (2024-05-14) - - - -## [2.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.2...v2.0.3) (2024-02-12) - - - -## [2.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.0...v2.0.2) (2024-02-10) - - - -# [2.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.1...v2.0.0) (2024-02-05) - - - -## [1.9.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.9.0...v1.9.1) (2023-11-21) - - - -# [1.9.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.2...v1.9.0) (2023-09-16) - - - -## [1.8.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.1...v1.8.2) (2023-07-26) - - - -## [1.8.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.8.0...v1.8.1) (2023-04-08) - - - -# [1.8.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0) (2023-01-29) - - - -## [1.7.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.2...v1.7.3) (2023-01-05) - - - -## [1.7.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.1...v1.7.2) (2022-12-26) - - - -## [1.7.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.0...v1.7.1) (2022-12-20) - - - -# [1.7.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.1...v1.7.0) (2022-12-08) - - - -## [1.6.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.6.0...v1.6.1) (2022-10-19) - - - -# [1.6.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.5.0...v1.6.0) (2022-10-18) - - - -# [1.5.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.1...v1.5.0) (2022-10-07) - - - -## [1.4.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.4.0...v1.4.1) (2022-08-27) - - - -# [1.4.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.3.0...v1.4.0) (2022-08-20) - - - -# [1.3.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.2.0...v1.3.0) (2022-06-25) - - - -# [1.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.2...v1.2.0) (2022-03-04) - - - -## [1.1.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.1...v1.1.2) (2021-11-13) - - - -## [1.1.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.1.0...v1.1.1) (2021-11-02) - - - -# [1.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.8...v1.1.0) (2021-10-27) - - - -## [1.0.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.7...v1.0.8) (2021-09-30) - - - -## [1.0.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.6...v1.0.7) (2021-09-25) - - - -## [1.0.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.5...v1.0.6) (2021-08-29) - - - -## [1.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.4...v1.0.5) (2021-08-04) - - - -## [1.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.3...v1.0.4) (2021-08-04) - - - -## [1.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.2...v1.0.3) (2021-07-30) - - - -## [1.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.1...v1.0.2) (2021-07-29) - - - -## [1.0.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v1.0.0...v1.0.1) (2021-07-29) - - - -# [1.0.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.2.0...v1.0.0) (2021-01-21) - - - -# [0.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.1.0...v0.2.0) (2020-11-05) - - - -# [0.1.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.5...v0.1.0) (2020-10-28) +* **Hybrid Architecture**: Unified BLE-first approach with automatic OpenAPI fallback +* **Automatic Discovery**: Combined BLE + OpenAPI device discovery in single call +* **Smart Fallback**: Commands automatically retry via API when BLE fails +* **Device Manager**: Centralized device management with `get()`, `list()`, and `clear()` methods +* **Expanded Device Coverage**: Added support and parsing updates across newly modeled devices and accessories in the v4 architecture. +* **macOS BLE Support**: Enabled BLE functionality on macOS in addition to Linux + * Platform detection now includes macOS (`darwin`) using `@stoprocent/noble` + * BLE now works on Linux and macOS systems + * Windows remains unsupported for BLE operations +* **Bot Password Protection**: Added BLE password support for Bot (`WoHand`) devices + * Password encryption using CRC32 checksums + * Password validation for 4 alphanumeric characters, case-sensitive + * Methods: `setPassword()`, `clearPassword()`, `hasPassword()` + * Automatic encrypted command execution when password is set + * Example: `examples/bot-password.js` + * Based on [homebridge-switchbot PR #1337](https://github.com/OpenWonderLabs/homebridge-switchbot/pull/1337) +* **Advanced Resilience Features**: Enterprise-grade reliability enhancements + * Retry logic with exponential backoff and jitter + * Circuit breaker pattern to prevent cascading failures + * Connection intelligence tracking per-device success and failure rates + * Custom fallback handler system for logging, metrics, and alerting + * Intelligent connection selection based on historical performance +* **Event-Driven**: EventEmitter-based architecture for discovery and command events +* **TypeScript Native**: Written in TypeScript with full type safety and exports +* **Custom Errors**: Specific error classes for better error handling +* **BLE-Only Mode**: Works without OpenAPI credentials on Linux/macOS systems +* **API-Only Mode**: Works without BLE on Windows systems +* **Exports and API Surface Updates**: Updated `src/index.ts` exports for final v4 public API packaging. +* **Comprehensive Examples**: Updated and aligned example files for v4 usage patterns. + +### Technical Improvements + +* Complete ES2022 module implementation +* Improved error handling with custom error classes +* Better connection management and timeout handling +* Enhanced logging with configurable log levels +* Hardened dependency graph with security overrides for vulnerable transitive packages +* Full JSDoc documentation coverage +* Comprehensive TypeScript type definitions for all devices +* Reworked test suite structure and coverage for APIs, devices, and utilities +* Auto-formatting and linting with @antfu/eslint-config + +### Documentation + +* Updated README with v4 quick start and migration guide +* 6 usage examples in `examples/` directory +* Migration guide from v3.x to v4.0.0 +* Added password protection section to [BLE.md](BLE.md) +* Updated [README.md](README.md) with password examples +* Created comprehensive password protection example +* Updated examples index with `bot-password.js` +* Updated platform support documentation to reflect macOS BLE support +* Updated Linux-only references to Linux/macOS where applicable +* Added comprehensive prerequisites guidance for BLE setup on macOS and Linux + * macOS: Xcode and Bluetooth permissions requirements + * Linux: system packages, non-root setup, and Raspberry Pi notes + * Based on [@stoprocent/noble prerequisites](https://github.com/stoprocent/noble?tab=readme-ov-file#prerequisites) +* Full API documentation via TypeDoc + +### Tests + +* Added 14 comprehensive password protection tests +* Validation for CRC32 encryption, command building, and response parsing +* Extended fallback and retry behavior coverage across BLE/API paths +* 58 test files and 243 passing tests at release validation + +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.8...v4.0.0 + +## [3.6.8](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.7...v3.6.8) (2026-03-05) + +### Changes + +* Fix BLE parsing and device registration flow for `WoAirPurifier` and `WoAirPurifierTable`. +* Improve service data fallback handling and mode mapping for Air Purifier family devices. + +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.7...v3.6.8 + +## [3.6.7](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.6...v3.6.7) (2026-03-05) + +### Changes + +* Fix `WoPlugMiniUS` `TypeError` in device handling and command flow. + +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.6...v3.6.7 +## [3.6.6](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.5...v3.6.6) (2026-02-25) ### Bug Fixes -* typo ([338044f](https://github.com/OpenWonderLabs/node-switchbot/commit/338044f3469788f76c189ba75be80518b1765107)) - +* sync package-lock.json with @stoprocent/noble@^2.3.14 ([#324](https://github.com/OpenWonderLabs/node-switchbot/issues/324)) ([0670987](https://github.com/OpenWonderLabs/node-switchbot/commit/06709876ab1bb4adc244507863f1b25b786b87f2)) ### Features -* Added support for running on the Raspberry Pi Zero W. ([017b244](https://github.com/OpenWonderLabs/node-switchbot/commit/017b244cfba178827b4a2504853cc013b7a6bc70)) - - +* Add Plug Mini (EU) support ([#325](https://github.com/OpenWonderLabs/node-switchbot/issues/325)) ([1eb8d2e](https://github.com/OpenWonderLabs/node-switchbot/commit/1eb8d2e572e211482105c2563a736bdfabeb50be)) -## [0.0.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.4...v0.0.5) (2020-02-18) +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.5...v3.6.6 +## [3.6.5](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.4...v3.6.5) (2026-02-19) +### Changes -## [0.0.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.3...v0.0.4) (2020-02-10) +* Bump `@stoprocent/noble` to `2.3.14` for BLE stability and compatibility updates. +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.4...v3.6.5 +## [3.6.4](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4) (2026-02-18) -## [0.0.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.2...v0.0.3) (2020-02-10) +### Changes +* Fix BLE parsing for Air Purifier PM2.5 service data. +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.3...v3.6.4 -## [0.0.2](https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2) (2019-11-20) +## [3.6.3](https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.2...v3.6.3) (2026-02-05) +### Changes +* Add Lock Ultra device support. -## 0.0.1 (2019-11-20) +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v3.6.2...v3.6.3 ## [3.6.2](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v3.6.2) (2025-12-18) @@ -1564,7 +375,6 @@ All notable changes to this project will be documented in this file. This projec - Add SwitchBot Lock Support [#232](https://github.com/OpenWonderLabs/node-switchbot/pull/232), Thanks [@brozef](https://github.com/brozef) - Fix TypeScript issues & warnings [#239](https://github.com/OpenWonderLabs/node-switchbot/pull/239) [#240](https://github.com/OpenWonderLabs/node-switchbot/pull/240) [#241](https://github.com/OpenWonderLabs/node-switchbot/pull/241), Thanks [@dnicolson](https://github.com/dnicolson) - Update Noble [#242](https://github.com/OpenWonderLabs/node-switchbot/pull/242), Thanks [@dnicolson](https://github.com/dnicolson) -dnicolson - Housekeeping and update dependencies **Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v2.0.3...v2.1.0 @@ -1904,8 +714,12 @@ dnicolson - First public release +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v0.0.1...v0.0.2 + ## [0.0.1](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v0.0.1) (2019-11-20) ### What's Changed - Initial commit + +**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v0.0.1 diff --git a/OpenAPI.md b/OpenAPI.md index bdea49d1..aaca17da 100644 --- a/OpenAPI.md +++ b/OpenAPI.md @@ -1,186 +1,220 @@ # SwitchBot OpenAPI Documentation -The `SwitchBotOpenAPI` class allows you to interact with SwitchBot devices using the SwitchBot OpenAPI. This documentation provides an overview of how to install, set up, and use the various methods available in the `SwitchBotOpenAPI` class. +OpenAPI support in `node-switchbot` is part of the v4 unified architecture. The primary public API is the `SwitchBot` class, which can run in API-only mode or in hybrid BLE + OpenAPI mode. -## Table of Contents +This document covers: -- [OpenAPI](#openapi) - - [Importing and Setting Up](#importing-and-setting-up) - - [`SwitchBotOpenAPI` Object](#switchbotopenapi-object) - - [`getDevices()` Method](#getdevices-method) - - [`controlDevice()` Method](#controldevice-method) - - [`getDeviceStatus()` Method](#getdevicestatus-method) - - [`setupWebhook()` Method](#setupwebhook-method) - - [`deleteWebhook()` Method](#deletewebhook-method) - - [Logging](#logging) - - [Supported Devices](#supported-devices) +- Using OpenAPI through the unified `SwitchBot` class +- Running in API-only mode +- Using the lower-level `OpenAPIClient` directly +- Webhook and scene helpers exposed by `OpenAPIClient` -## OpenAPI +## v4 OpenAPI Model -### Importing and Setting Up +In v4.0.0: -To use the `SwitchBotOpenAPI` class, you need to import it and create an instance with your SwitchBot token and secret. +- `SwitchBot` is the recommended entry point +- OpenAPI is enabled when `token` and `secret` are provided +- You can run API-only by setting `enableBLE: false` +- You can run hybrid mode by combining credentials with `enableBLE: true` +- Discovered devices are accessed through `switchbot.devices` -```typescript -import { SwitchBotOpenAPI } from 'node-switchbot' +## Credentials -const switchBotAPI = new SwitchBotOpenAPI('your-token', 'your-secret') +To use OpenAPI, you need a SwitchBot token and secret. -// Example usage -switchBotAPI.getDevices().then((devices) => { - console.log('Devices:', devices) -}).catch((error) => { - console.error('Error getting devices:', error) -}) -``` +In the SwitchBot mobile app: -### SwitchBotOpenAPI Object +1. Open your profile +2. Open preferences +3. Tap the app version multiple times to unlock developer options +4. Copy your token and secret -The `SwitchBotOpenAPI` object provides several methods to interact with SwitchBot devices. Below are examples of how to use each method. +## API-Only Mode -#### `getDevices()` Method - -Fetches the list of devices associated with your SwitchBot account. +Use this mode on Windows or anywhere you want cloud-only operation. ```typescript -async function getDevices() { - try { - const devices = await switchBotAPI.getDevices() - console.log('Devices:', devices) - } catch (e: any) { - console.error(`failed to get devices, Error: ${e.message ?? e}`) - } -} +import { LogLevel, SwitchBot } from 'node-switchbot' -// Example usage -getDevices() -``` +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: false, + logLevel: LogLevel.INFO, +}) -#### `controlDevice()` Method +const devices = await switchbot.discover({ + scanBLE: false, + fetchAPI: true, +}) -Sends a command to control a specific device. +console.log(`Found ${devices.length} device(s) from OpenAPI`) -```typescript -async function controlDevice(deviceId, command, parameter) { - try { - const response = await switchBotAPI.controlDevice(deviceId, command, parameter) - console.log('Control Device Response:', response) - } catch (error) { - console.error('Error controlling device:', error) - } +const bot = switchbot.devices.get('YOUR_DEVICE_ID') +if (bot) { + await bot.turnOn() + const status = await bot.getStatus() + console.log(status) } -// Example usage -controlDevice('your-device-id', 'turnOn', 'default') +await switchbot.cleanup() ``` -#### `getDeviceStatus()` Method +## Hybrid Mode -Fetches the current status of a specific device. +If you want local BLE when available and cloud fallback when needed: ```typescript -async function getDeviceStatus(deviceId) { - try { - const status = await switchBotAPI.getDeviceStatus(deviceId) - console.log('Device Status:', status) - } catch (error) { - console.error('Error getting device status:', error) - } +import { LogLevel, SwitchBot } from 'node-switchbot' + +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: true, + enableFallback: true, + enableConnectionIntelligence: true, + enableCircuitBreaker: true, + enableRetry: true, + logLevel: LogLevel.INFO, +}) + +await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10_000, +}) + +const lock = switchbot.devices.get('YOUR_LOCK_ID') +if (lock) { + await lock.lock() } -// Example usage -getDeviceStatus('your-device-id') +await switchbot.cleanup() ``` -#### `setupWebhook()` Method +## Discovery Through OpenAPI -Sets up a webhook to receive events from SwitchBot devices. +When OpenAPI is enabled, `switchbot.discover()` can fetch cloud-registered devices and merge them with BLE discoveries. -```typescript -async function setupWebhook(url) { - try { - await switchBotAPI.setupWebhook(url) - console.log('Webhook setup successfully') - } catch (error) { - console.error('Error setting up webhook:', error) - } -} +Supported discovery options: -// Example usage -setupWebhook('http://your-webhook-url') +| Property | Type | Description | +| :-- | :-- | :-- | +| `scanBLE` | `boolean` | Enable BLE discovery for this call | +| `fetchAPI` | `boolean` | Enable OpenAPI device fetch for this call | +| `timeout` | `number` | Discovery timeout in milliseconds | +| `deviceId` | `string` | Filter by SwitchBot device ID | +| `mac` | `string` | Filter by MAC address | +| `deviceType` | `string` | Filter by device type | + +## Device Manager Pattern + +After discovery: + +```typescript +const devices = switchbot.devices.list() +const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') +const locks = switchbot.devices.getByType('WoSmartLock') ``` -#### `deleteWebhook()` Method +Every discovered device exposes the unified command surface for its class, regardless of whether the eventual command runs over API, BLE, or a fallback path. -Deletes an existing webhook. +## Lower-Level `OpenAPIClient` + +If you need direct access to the SwitchBot cloud API without the full hybrid layer, use `OpenAPIClient`. ```typescript -async function deleteWebhook(url) { - try { - await switchBotAPI.deleteWebhook(url) - console.log('Webhook deleted successfully') - } catch (error) { - console.error('Error deleting webhook:', error) - } -} +import { OpenAPIClient } from 'node-switchbot' + +const api = new OpenAPIClient('YOUR_TOKEN', 'YOUR_SECRET') + +const devices = await api.getDevices() +console.log(devices) + +const status = await api.getStatus('YOUR_DEVICE_ID') +console.log(status) -// Example usage -deleteWebhook('http://your-webhook-url') +await api.sendCommand('YOUR_DEVICE_ID', 'turnOn') ``` -### Logging +### Core Methods + +| Method | Description | +| :-- | :-- | +| `getDevices()` | Fetch cloud devices | +| `getStatus(deviceId)` | Fetch device status | +| `sendCommand(deviceId, command, parameter?)` | Send a raw OpenAPI command | +| `getScenes()` | Fetch scenes | +| `executeScene(sceneId)` | Run a scene | + +### Webhook Methods + +| Method | Description | +| :-- | :-- | +| `setupWebhook(config)` | Register a webhook | +| `queryWebhook(urls?)` | Query existing webhook configuration | +| `updateWebhook(config)` | Update a webhook | +| `deleteWebhook(url)` | Remove a webhook | + +### Convenience Methods -To be able to receive logging that this module is pushing out you will need to subscribt to the events. +The client also exposes convenience wrappers for common device families, including Bot and Curtain helpers. + +Examples: + +- `botPress(deviceId)` +- `botTurnOn(deviceId)` +- `botTurnOff(deviceId)` +- `curtainOpen(deviceId, speed?)` +- `curtainClose(deviceId, speed?)` +- `curtainPause(deviceId)` +- `curtainSetPosition(deviceId, position, speed?)` + +## Logging + +In v4, logging is configured through the unified constructor rather than through a legacy event-emitter API shown in older docs. + +Example using the main `SwitchBot` class: ```typescript -this.switchBotAPI.on('log', (log) => { - switch (log.level) { - case LogLevel.SUCCESS: - this.successLog(log.message) - break - case LogLevel.DEBUGSUCCESS: - this.debugSuccessLog(log.message) - break - case LogLevel.WARN: - this.warnLog(log.message) - break - case LogLevel.DEBUGWARN: - this.debugWarnLog(log.message) - break - case LogLevel.ERROR: - this.errorLog(log.message) - break - case LogLevel.DEBUGERROR: - this.debugErrorLog(log.message) - break - case LogLevel.DEBUG: - this.debugLog(log.message) - break - case LogLevel.INFO: - default: - this.infoLog(log.message) - } +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: false, + logger: { + error: console.error, + warn: console.warn, + info: console.info, + debug: console.debug, + }, }) ``` -### Supported Devices +## OpenAPI-Supported Device Families + +OpenAPI support generally includes the major SwitchBot cloud-connected device families, such as: + +- Bot +- Curtain and Roller Shade +- Meter family +- Contact and motion or presence sensors +- Plug Mini family +- Lock family +- Humidifier and air purifier family +- Bulb and strip light family +- Hub-connected devices supported by the SwitchBot cloud + +Actual availability depends on SwitchBot cloud support for the device and whether cloud service is enabled in your account. + +## Relationship to BLE -The following devices are supported. +OpenAPI docs are no longer separate from the main product model. In v4: -| Device | OpenAPI Support | Webhook Support | -| ---------------------------------------------- | --------------- | --------------- | -| SwitchBot Bot | Yes | Yes | -| SwitchBot Curtain | Yes | Yes | -| SwitchBot Meter | Yes | Yes | -| SwitchBot Motion Sensor | Yes | Yes | -| SwitchBot Contact Sensor | Yes | Yes | -| SwitchBot Plug Min | Yes | Yes | -| SwitchBot Smart Lock | Yes | Yes | -| SwitchBot Humidifier | Yes | Yes | -| SwitchBot Evaporative Humidifier (Auto-refill) | Yes | Yes | -| SwitchBot Color Bulb | Yes | Yes | -| SwitchBot LED Strip Light | Yes | Yes | +- Use [BLE.md](BLE.md) for platform-specific BLE prerequisites and low-level BLE helpers +- Use this document for cloud API behavior and `OpenAPIClient` +- Use the main README for the high-level v4 migration and quick-start path -### Summary +## Summary -The `SwitchBotOpenAPI` class provides a powerful way to interact with your SwitchBot devices programmatically. By following the examples provided, you can easily integrate SwitchBot device control and monitoring into your applications. +Use `SwitchBot` for most v4 applications. Use `OpenAPIClient` only when you want direct cloud API access without the device abstraction and hybrid connection logic. diff --git a/README.md b/README.md index 7f3885ff..76fb3b68 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,76 @@ To install the `node-switchbot` module within your project, use the following co $ npm install --save node-switchbot ``` +--- + +## Quick Start (v4.0.0) + +**v4.0.0** introduces a unified hybrid approach that automatically uses BLE when available with seamless API fallback. + +### Basic Usage + +```javascript +import { SwitchBot } from 'node-switchbot' + +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', // OpenAPI token (optional for BLE-only) + secret: 'YOUR_SECRET', // OpenAPI secret (optional for BLE-only) + enableBLE: true, // Enable BLE discovery (Linux/macOS) + enableFallback: true, // Auto-fallback between BLE/API +}) + +// Discover all devices (BLE + API) +const devices = await switchbot.discover() + +// Control devices +const bot = switchbot.devices.get('YOUR_DEVICE_ID') +await bot.press() + +// Get status +const status = await bot.getStatus() +console.log(status) + +// Cleanup +await switchbot.cleanup() +``` + +### Device Control Examples + +```javascript +// Bot - Press/Switch control +await bot.turnOn() +await bot.turnOff() +await bot.press() + +// Bot with Password Protection (BLE only) +const protectedBot = new WoHand({ id: 'YOUR_BOT_ID', password: 'A1b2' }) +await protectedBot.setPassword('A1b2') // Set 4-char alphanumeric password +await protectedBot.press() // Commands are automatically encrypted +await protectedBot.clearPassword() // Remove password protection + +// Curtain - Position control +await curtain.open() +await curtain.close() +await curtain.setPosition(50) // 50% open + +// Lock - Lock/Unlock +await lock.lock() +await lock.unlock() + +// Bulb - Color and brightness +await bulb.turnOn() +await bulb.setBrightness(80) +await bulb.setColor(255, 0, 0) // Red + +// Meter - Read sensors +const meterStatus = await meter.getStatus() +console.log(meterStatus.temperature, meterStatus.humidity) +``` + +See the [examples directory](https://github.com/OpenWonderLabs/node-switchbot/tree/latest/examples) for more usage patterns. + +--- + ## [BLE (Bluetooth Low Energy)](BLE.md) To see a breakdown of how to use the BLE functionality of this project, visit the [BLE (Bluetooth Low Energy)](BLE.md) documentation. @@ -33,6 +103,34 @@ To see a breakdown of how to use the BLE functionality of this project, visit th To see a breakdown of how to use the OpenAPI functionality of this project, visit the [OpenAPI](OpenAPI.md) documentation. +--- + +## Migration from v3.x + +**Breaking Changes in v4.0.0:** + +- ✨ **Unified API**: Single `SwitchBot` class replaces separate `SwitchBotBLE` and `SwitchBotOpenAPI` classes +- 🔄 **Automatic Discovery**: Combined BLE + OpenAPI discovery in one call +- 🛡️ **Automatic Fallback**: BLE commands automatically fall back to API on failure +- 📦 **Device Manager**: Access devices via `switchbot.devices.get(id)` instead of direct discovery results +- 🏷️ **TypeScript**: Full TypeScript rewrite with comprehensive type definitions +- ⚠️ **No Backward Compatibility**: v3.x APIs are not supported - migration required + +**Migration Example:** + +```javascript +// v3.x (old) +import { SwitchBotBLE, SwitchBotOpenAPI } from 'node-switchbot' +const ble = new SwitchBotBLE() +const api = new SwitchBotOpenAPI(token, secret) + +// v4.0.0 (new) +import { SwitchBot } from 'node-switchbot' +const switchbot = new SwitchBot({ token, secret, enableBLE: true }) +``` + +--- + ## References - [SwitchBot (Official website)](https://www.switch-bot.com/) diff --git a/docs/assets/hierarchy.js b/docs/assets/hierarchy.js index 617fc6a3..7ac50e77 100644 --- a/docs/assets/hierarchy.js +++ b/docs/assets/hierarchy.js @@ -1 +1 @@ -window.hierarchyData = "eJyVls1O3DAURt/F69via8dxnF1LF7QFEXVALBCLTGIYi/wgx2mF0Lx7FUWFeBhidxVN5ss59pWv7Rdi+94NJL/lVAjglN4Bsfq+0ZUzfTeQ/IVwSqdHV7aa5GTzx7hqt+3dN/3bVJoAeTRdTXJkGZDRNiQnVVMOgx5ODqKfd65tCMx/k5y4of40fftpfgGk2pmmtroj+W3CEARySCkHSSnIVECWSFBMgFIUcBotIs8AGUNAlklALjhgggowURmgkBIwFQgoWQIolQTMUgaomARUigGjQgJDxoExToFxLoEl009Bxd0eSMJwMfWb/mtjuvrKNG5t2otYYMp7IAK5bxibbQA+NtswN6U+91SbxnQP5+ZhFxj8Mhn2SG9x3PSnfefKKqSYQxH0VPj00brSdAH6HArTs0R69LOyq9fRUyLMVcwf9dm4ZQHuuGURXEUPuTzI5WHu1EwH4NaEwK2JACPP3oGDpWhNRC2mtvfQ3y83uht6e3W2zn/LxUgyf4X81M9PZWCNzJkIOBd+i57r8nEdPSUiwAkqD1w048OF6cyPYh3/louRqOyo5HoTJ7neREiE9OtfWD3obv3UeUtFCFLhr6Jfuimf53ML1yXLZIRIsuRDUXERryouYmRKHsja3gWKNmci4FnKPHhc2/1H0ykmjwqKZhziJFMyRqSOz6SwfaTH9mHNdMn4SHN6GdgN/WyEDJm/qWza0rrzvgrsLK+xCAXj9LgiXLdFMkLE+UHhnDVPAcMUiUAnB2X6YmwxWnNvtF0XLIIRGkHFR5qrctsEWvIwHRZy/ySv/Ss6E+k/iemctvdlpYeTev1y/pr0L+gcU5xuyNPznXHjSrfo1TXvHI2w7/f7v6S+BnI=" \ No newline at end of file +window.hierarchyData = "eJydm1tz27YSx78Ln9FT4g74LbbjJo2daCI3fuj0gZYQm1OKzKGonMl08t3PLCjLBEQJi74wsfMHfthdXBaX/FP0XTdsi4s/KaXaEFpqwwmlrDTw5f6rS0Ipt5JQqgX8q5CaUCopha8S8LWMcCMJLaWG3yoj/iJF7742bjXUXbstLv4puJHwR1ttXHFRLP9XD6vny264dt/rlStI8XfdrosLygwpdn1TXBSrptpu3fbXSPqf52HTFGT85+KiGLbrX6DsL+MvSLF6rpt179ri4k/JLVGGE2sUoUJxQhW1hGrLCROMEyaVJJxRTrjilojSaiIk40QoJYmkVBIJRktjJFHgFmUMI7RknBJacs3/+kkKye3EsrGVn767vq/XbjlUg7ve9XX7dNW17eiPc9Yiiud4gJdCEWGVhIYqwycNfejevH+3ezzXmL0kAfxJCsNkWHPdL3Z9/bV2faL+V2GOWZRyQxillDCmNDFCMDDQGnWqGYs7JtFNAXHaaGjEKdx99dic7dXHagSQWREC++Gmhx/Og/YqBECosIdcNnW7vq+b4TzhIEMgFLUhYtck+iAosjoHs4JQKxhhmjGiSqaJkdYQo5WGbgITQNCGq6pdN+6h6jeuv6023863J1YjjLaChUBXN3X7dFs/PSdcO1WmQTAkQlDdr3ZNNXT9TXV23omkCBRTOkQ19aYa3KJqXZMgTZQIkGBRtLp2qFYpv40iRPVShXPX1a4fqjrlrFGU0y2VZn4Whk4ZAG+arkN0u4MMYZOxYTf4reqrJ3fddf2nb65NTcqxOg2EZSYAvqva9XkIKBAVMxoG/93ukSUq3j2yrCWSS0m4sH5qgB9iHk/yOMIQYXVc8V3d1nfVMKTiEUgRKMVthNrUKcKmzvKZ3rtLH1m1qZPx2dSpAEHVNorE+09L1267/v7d+fpfdWkIZHwB5IP78a1K9NxRk+MuwSC75IaCz+CHGeaXeptIDUMlwjhu6EnQou/wrEXfIXAymqdvXfX3eQYoEBWraIZeVC0kG1fVZtHstvzDeUisRgANjYDN7glG4O+LBOqgQ0BsbNW+8B9LHOSPZVYXNNSvPrCpCbG927r2/BbsVZW2SzIZDqnPrql+jJs4eh4yVebYBssdkYJpIqXxGwH44WQjFnf4ZizuEBZLw07BWAaMoWBa8Ai26YZE9EYNonJj5EzlD/XwvFz1ziWmp1idBkJuHgJ/u3x/ld4SHGRZCRhXkigpxr0wK80x+aPr2oe6d5+7bw6RnM+XQZjNo7HvK3p4QGaCsRoBlGIWuBz6+hvW0KkcgdTRmcDnrmlcv3yu1qne+ipEYEw0+HBJAjJFCJMeKyXRJRNEU6WI5qWBngS/mW0BLDe4VoAybSpQ50GptXwiRGB4NDImpa8+JZK7UIuACVmGsE3VD7fdKpE5HGQ5AdSKKmIoFT5siqp58m2dmk8DKcJIrc08Kh25iTLLVCsMMUwrb6oVp/kP9U1icxCrEceBlIp5ICbLjcSY00d9IpTIXPdYj4CK6EzHV3L/7PpNtx2q4XO1ruEwBUE+LoTASxvFFObmBAwkiKp1dLLzOu0ntsITIQJjeRi1L9Vqt9ucJ4yanJFg4ZTYMk2JFZwSKy0lVktKrIUrjLLUfldm45OzkfSBlulpPJCmDYfGnEClOupUiQAJfhp01W0eM2hejkBKO4+keDdSpBu1nEWxEoVhJQJhZzvFkqIQS4pA+A44x8CZscSY4e+rAsZDNbj+2g1ulZyhAimGxfV0g7J0/93BxhFxzxcoc4a4YZLAtpNANkFgtSUwufij/lIG2dmbxfu3fX/e5hcNxljJeVj7x254872qG7jRwZCO9DjqdO6/vH2bRZ3To6jBzvOq22yqdn1T1Y1bJ5nHahRRsoD4cgN6X29ctxsQ1LkSOPLxne7Hbrjpdm3a2Bk5iqmmPfW63q66767/kcYFShQpmHIOF+xJUqjMupODcUj8ePFfeGwghf+7ZP5rifeAf0Sg90NXT/OQL1VTrysIZrKdkRTjEh10tcnd7NL1EM3raqgOSCbVC7JuB9d/rVYwmmcLnYQfSu4bEFzOX96+xYNDMQIYhUb7EGgLQTFUwde/bzBawxfefpSWQmisD5/1eqtAb+HdBy1LeBlSMnj9UQoGX2nHIOogTz3cFGdYN1ME61QT7PEuuxxs96+AwUILJ1QZxFCdH0cj4TVO+TJ8jJzOJ9OLZHybTpRCuyMYwfs72Qz6UQE02E4Pn/a3tRngowJYsA12vu92GfEPxWhgkIHA5do6c96aLYPGB/MmXOjgwZEajVTTGQW27RnIUI1GBufid27I8W8sR0JhUp1CO1jPMqixHo1l0ykMbpvw0EiNRgZHKS93TRnY4xJodJDoTW5j8PT5QugGBFOkP0HBo2M5FkqDA8lJ4rLP07f4VOelRO5yZcbXMJTS4Ap+mkQN1bDLaMmox7ogvP85JBlIBxzps1drofhoP2PzCRLG+kiNtj3cP3Zoq7t/bS+8ENrbq1iUk6Es7XJt1GWUiWGNnEizo+rfF1PO4Om0YnuLeZAT+DQPZfJBmN0MyjUk4UqX+xYEfWya1CGdMlcEGwmu2ak8FOOG4wJocPAc+CWZRDGnWjRuLufE+jdU5wYcHjGOkRZczyS+KJunWqzNIrhZggwWgzro0JjgTclrwor07nGB7OlLcbt3cJAKTnJnnOGhHG1/sEaOT7NQwKkUC5OliFN6DOpViAYFp+uQmiPjOZXmRvJwRjyGMzxK9dsDlLEHIdpYoY+2EBjSRIlGSXW8cUCxJlI0LDi1hA0AMohTaW4QX/5HC6VSx3iUpa9CtJ1GzO1RULBAjAZaNr8zQfp3pkSum+FSZXSzouWJbRLGAUd6rA8UC7HwvgxJfJXiYSreiSFdHWjRuCBBHXdyGNMmSjQq6LvjzSHStFCcvcl7uYajOthu7S8vMeZOpVh7wzeS43UMCjaV5ifd1ML/jGQ++WcKEnAOp+aQhxKfmRGfMBGfRBC/qhO/3BK/DhG/SBA/fxM/sxE/7RA//PyGAr4anp39/Pl/7zWl7A==" \ No newline at end of file diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css index 3b1320f3..e7a2cd03 100644 --- a/docs/assets/highlight.css +++ b/docs/assets/highlight.css @@ -7,12 +7,18 @@ --dark-hl-2: #CE9178; --light-hl-3: #0000FF; --dark-hl-3: #569CD6; - --light-hl-4: #0070C1; - --dark-hl-4: #4FC1FF; - --light-hl-5: #008000; - --dark-hl-5: #6A9955; - --light-hl-6: #001080; - --dark-hl-6: #9CDCFE; + --light-hl-4: #AF00DB; + --dark-hl-4: #C586C0; + --light-hl-5: #001080; + --dark-hl-5: #9CDCFE; + --light-hl-6: #0070C1; + --dark-hl-6: #4FC1FF; + --light-hl-7: #008000; + --dark-hl-7: #6A9955; + --light-hl-8: #098658; + --dark-hl-8: #B5CEA8; + --light-hl-9: #267F99; + --dark-hl-9: #4EC9B0; --light-code-background: #FFFFFF; --dark-code-background: #1E1E1E; } @@ -25,6 +31,9 @@ --hl-4: var(--light-hl-4); --hl-5: var(--light-hl-5); --hl-6: var(--light-hl-6); + --hl-7: var(--light-hl-7); + --hl-8: var(--light-hl-8); + --hl-9: var(--light-hl-9); --code-background: var(--light-code-background); } } @@ -36,6 +45,9 @@ --hl-4: var(--dark-hl-4); --hl-5: var(--dark-hl-5); --hl-6: var(--dark-hl-6); + --hl-7: var(--dark-hl-7); + --hl-8: var(--dark-hl-8); + --hl-9: var(--dark-hl-9); --code-background: var(--dark-code-background); } } @@ -47,6 +59,9 @@ --hl-4: var(--light-hl-4); --hl-5: var(--light-hl-5); --hl-6: var(--light-hl-6); + --hl-7: var(--light-hl-7); + --hl-8: var(--light-hl-8); + --hl-9: var(--light-hl-9); --code-background: var(--light-code-background); } @@ -58,6 +73,9 @@ --hl-4: var(--dark-hl-4); --hl-5: var(--dark-hl-5); --hl-6: var(--dark-hl-6); + --hl-7: var(--dark-hl-7); + --hl-8: var(--dark-hl-8); + --hl-9: var(--dark-hl-9); --code-background: var(--dark-code-background); } @@ -68,4 +86,7 @@ .hl-4 { color: var(--hl-4); } .hl-5 { color: var(--hl-5); } .hl-6 { color: var(--hl-6); } +.hl-7 { color: var(--hl-7); } +.hl-8 { color: var(--hl-8); } +.hl-9 { color: var(--hl-9); } pre, code { background: var(--code-background); } diff --git a/docs/assets/icons.js b/docs/assets/icons.js index 58882d76..3ae8f55e 100644 --- a/docs/assets/icons.js +++ b/docs/assets/icons.js @@ -3,7 +3,7 @@ function addIcons() { if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons); const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); - svg.innerHTML = `MMNEPVFCICPMFPCPTTAAATR`; + svg.innerHTML = `MMNEPVFCICPMFPCPTTAAATR`; svg.style.display = "none"; if (location.protocol === "file:") updateUseElements(); } diff --git a/docs/assets/icons.svg b/docs/assets/icons.svg index 50ad5799..10db10be 100644 --- a/docs/assets/icons.svg +++ b/docs/assets/icons.svg @@ -1 +1 @@ -MMNEPVFCICPMFPCPTTAAATR \ No newline at end of file +MMNEPVFCICPMFPCPTTAAATR \ No newline at end of file diff --git a/docs/assets/main.js b/docs/assets/main.js index 19bbb7a7..11d92ad6 100644 --- a/docs/assets/main.js +++ b/docs/assets/main.js @@ -1,7 +1,7 @@ "use strict"; window.translations={"copy":"Copy","copied":"Copied!","normally_hidden":"This member is normally hidden due to your filter settings.","hierarchy_expand":"Expand","hierarchy_collapse":"Collapse","folder":"Folder","search_index_not_available":"The search index is not available","search_no_results_found_for_0":"No results found for {0}","kind_1":"Project","kind_2":"Module","kind_4":"Namespace","kind_8":"Enumeration","kind_16":"Enumeration Member","kind_32":"Variable","kind_64":"Function","kind_128":"Class","kind_256":"Interface","kind_512":"Constructor","kind_1024":"Property","kind_2048":"Method","kind_4096":"Call Signature","kind_8192":"Index Signature","kind_16384":"Constructor Signature","kind_32768":"Parameter","kind_65536":"Type Literal","kind_131072":"Type Parameter","kind_262144":"Accessor","kind_524288":"Get Signature","kind_1048576":"Set Signature","kind_2097152":"Type Alias","kind_4194304":"Reference","kind_8388608":"Document"}; -"use strict";(()=>{var Ke=Object.create;var he=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ye=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var tt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ze(e))!Ye.call(t,i)&&i!==n&&he(t,i,{get:()=>e[i],enumerable:!(r=Ge(e,i))||r.enumerable});return t};var nt=(t,e,n)=>(n=t!=null?Ke(Xe(t)):{},tt(e||!t||!t.__esModule?he(n,"default",{value:t,enumerable:!0}):n,t));var ye=et((me,ge)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,l],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(oc?d+=2:a==c&&(n+=r[l+1]*i[d+1],l+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}if(s.str.length==0&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),f=s.str.charAt(1),p;f in s.node.edges?p=s.node.edges[f]:(p=new t.TokenSet,s.node.edges[f]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),c=0;c1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof me=="object"?ge.exports=n():e.lunr=n()}(this,function(){return t})})()});var M,G={getItem(){return null},setItem(){}},K;try{K=localStorage,M=K}catch{K=G,M=G}var S={getItem:t=>M.getItem(t),setItem:(t,e)=>M.setItem(t,e),disableWritingLocalStorage(){M=G},disable(){localStorage.clear(),M=G},enable(){M=K}};window.TypeDoc||={disableWritingLocalStorage(){S.disableWritingLocalStorage()},disableLocalStorage:()=>{S.disable()},enableLocalStorage:()=>{S.enable()}};window.translations||={copy:"Copy",copied:"Copied!",normally_hidden:"This member is normally hidden due to your filter settings.",hierarchy_expand:"Expand",hierarchy_collapse:"Collapse",search_index_not_available:"The search index is not available",search_no_results_found_for_0:"No results found for {0}",folder:"Folder",kind_1:"Project",kind_2:"Module",kind_4:"Namespace",kind_8:"Enumeration",kind_16:"Enumeration Member",kind_32:"Variable",kind_64:"Function",kind_128:"Class",kind_256:"Interface",kind_512:"Constructor",kind_1024:"Property",kind_2048:"Method",kind_4096:"Call Signature",kind_8192:"Index Signature",kind_16384:"Constructor Signature",kind_32768:"Parameter",kind_65536:"Type Literal",kind_131072:"Type Parameter",kind_262144:"Accessor",kind_524288:"Get Signature",kind_1048576:"Set Signature",kind_2097152:"Type Alias",kind_4194304:"Reference",kind_8388608:"Document"};var pe=[];function X(t,e){pe.push({selector:e,constructor:t})}var Z=class{alwaysVisibleMember=null;constructor(){this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){pe.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!rt(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function rt(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var fe=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var Ie=nt(ye(),1);async function R(t){let e=Uint8Array.from(atob(t),s=>s.charCodeAt(0)),r=new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate")),i=await new Response(r).text();return JSON.parse(i)}var Y="closing",ae="tsd-overlay";function it(){let t=Math.abs(window.innerWidth-document.documentElement.clientWidth);document.body.style.overflow="hidden",document.body.style.paddingRight=`${t}px`}function st(){document.body.style.removeProperty("overflow"),document.body.style.removeProperty("padding-right")}function xe(t,e){t.addEventListener("animationend",()=>{t.classList.contains(Y)&&(t.classList.remove(Y),document.getElementById(ae)?.remove(),t.close(),st())}),t.addEventListener("cancel",n=>{n.preventDefault(),ve(t)}),e?.closeOnClick&&document.addEventListener("click",n=>{t.open&&!t.contains(n.target)&&ve(t)},!0)}function Ee(t){if(t.open)return;let e=document.createElement("div");e.id=ae,document.body.appendChild(e),t.showModal(),it()}function ve(t){if(!t.open)return;document.getElementById(ae)?.classList.add(Y),t.classList.add(Y)}var I=class{el;app;constructor(e){this.el=e.el,this.app=e.app}};var be=document.head.appendChild(document.createElement("style"));be.dataset.for="filters";var le={};function we(t){for(let e of t.split(/\s+/))if(le.hasOwnProperty(e)&&!le[e])return!0;return!1}var ee=class extends I{key;value;constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),be.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } +"use strict";(()=>{var Ke=Object.create;var he=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ye=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var tt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ze(e))!Ye.call(t,i)&&i!==n&&he(t,i,{get:()=>e[i],enumerable:!(r=Ge(e,i))||r.enumerable});return t};var nt=(t,e,n)=>(n=t!=null?Ke(Xe(t)):{},tt(e||!t||!t.__esModule?he(n,"default",{value:t,enumerable:!0}):n,t));var ye=et((me,ge)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=(function(e){return function(n){e.console&&console.warn&&console.warn(n)}})(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,l],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(oc?d+=2:a==c&&(n+=r[l+1]*i[d+1],l+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}if(s.str.length==0&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),f=s.str.charAt(1),p;f in s.node.edges?p=s.node.edges[f]:(p=new t.TokenSet,s.node.edges[f]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),c=0;c1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}if(s.type===t.QueryLexer.TERM)return t.QueryParser.parseTerm;var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},(function(e,n){typeof define=="function"&&define.amd?define(n):typeof me=="object"?ge.exports=n():e.lunr=n()})(this,function(){return t})})()});var M,G={getItem(){return null},setItem(){}},K;try{K=localStorage,M=K}catch{K=G,M=G}var S={getItem:t=>M.getItem(t),setItem:(t,e)=>M.setItem(t,e),disableWritingLocalStorage(){M=G},disable(){localStorage.clear(),M=G},enable(){M=K}};window.TypeDoc||={disableWritingLocalStorage(){S.disableWritingLocalStorage()},disableLocalStorage:()=>{S.disable()},enableLocalStorage:()=>{S.enable()}};window.translations||={copy:"Copy",copied:"Copied!",normally_hidden:"This member is normally hidden due to your filter settings.",hierarchy_expand:"Expand",hierarchy_collapse:"Collapse",search_index_not_available:"The search index is not available",search_no_results_found_for_0:"No results found for {0}",folder:"Folder",kind_1:"Project",kind_2:"Module",kind_4:"Namespace",kind_8:"Enumeration",kind_16:"Enumeration Member",kind_32:"Variable",kind_64:"Function",kind_128:"Class",kind_256:"Interface",kind_512:"Constructor",kind_1024:"Property",kind_2048:"Method",kind_4096:"Call Signature",kind_8192:"Index Signature",kind_16384:"Constructor Signature",kind_32768:"Parameter",kind_65536:"Type Literal",kind_131072:"Type Parameter",kind_262144:"Accessor",kind_524288:"Get Signature",kind_1048576:"Set Signature",kind_2097152:"Type Alias",kind_4194304:"Reference",kind_8388608:"Document"};var pe=[];function X(t,e){pe.push({selector:e,constructor:t})}var Z=class{alwaysVisibleMember=null;constructor(){this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){pe.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!rt(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function rt(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var fe=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var Ie=nt(ye(),1);async function R(t){let e=Uint8Array.from(atob(t),s=>s.charCodeAt(0)),r=new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate")),i=await new Response(r).text();return JSON.parse(i)}var Y="closing",ae="tsd-overlay";function it(){let t=Math.abs(window.innerWidth-document.documentElement.clientWidth);document.body.style.overflow="hidden",document.body.style.paddingRight=`${t}px`}function st(){document.body.style.removeProperty("overflow"),document.body.style.removeProperty("padding-right")}function xe(t,e){t.addEventListener("animationend",()=>{t.classList.contains(Y)&&(t.classList.remove(Y),document.getElementById(ae)?.remove(),t.close(),st())}),t.addEventListener("cancel",n=>{n.preventDefault(),ve(t)}),e?.closeOnClick&&document.addEventListener("click",n=>{t.open&&!t.contains(n.target)&&ve(t)},!0)}function Ee(t){if(t.open)return;let e=document.createElement("div");e.id=ae,document.body.appendChild(e),t.showModal(),it()}function ve(t){if(!t.open)return;document.getElementById(ae)?.classList.add(Y),t.classList.add(Y)}var I=class{el;app;constructor(e){this.el=e.el,this.app=e.app}};var be=document.head.appendChild(document.createElement("style"));be.dataset.for="filters";var le={};function we(t){for(let e of t.split(/\s+/))if(le.hasOwnProperty(e)&&!le[e])return!0;return!1}var ee=class extends I{key;value;constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),be.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } `,this.app.updateIndexVisibility()}fromLocalStorage(){let e=S.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){S.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),le[`tsd-is-${this.el.name}`]=this.value,this.app.filterChanged(),this.app.updateIndexVisibility()}};var Le=0;async function Se(t,e){if(!window.searchData)return;let n=await R(window.searchData);t.data=n,t.index=Ie.Index.load(n.index),e.innerHTML=""}function _e(){let t=document.getElementById("tsd-search-trigger"),e=document.getElementById("tsd-search"),n=document.getElementById("tsd-search-input"),r=document.getElementById("tsd-search-results"),i=document.getElementById("tsd-search-script"),s=document.getElementById("tsd-search-status");if(!(t&&e&&n&&r&&i&&s))throw new Error("Search controls missing");let o={base:document.documentElement.dataset.base};o.base.endsWith("/")||(o.base+="/"),i.addEventListener("error",()=>{let a=window.translations.search_index_not_available;Pe(s,a)}),i.addEventListener("load",()=>{Se(o,s)}),Se(o,s),ot({trigger:t,searchEl:e,results:r,field:n,status:s},o)}function ot(t,e){let{field:n,results:r,searchEl:i,status:s,trigger:o}=t;xe(i,{closeOnClick:!0});function a(){Ee(i),n.setSelectionRange(0,n.value.length)}o.addEventListener("click",a),n.addEventListener("input",fe(()=>{at(r,n,s,e)},200)),n.addEventListener("keydown",l=>{if(r.childElementCount===0||l.ctrlKey||l.metaKey||l.altKey)return;let d=n.getAttribute("aria-activedescendant"),f=d?document.getElementById(d):null;if(f){let p=!1,v=!1;switch(l.key){case"Home":case"End":case"ArrowLeft":case"ArrowRight":v=!0;break;case"ArrowDown":case"ArrowUp":p=l.shiftKey;break}(p||v)&&ke(n)}if(!l.shiftKey)switch(l.key){case"Enter":f?.querySelector("a")?.click();break;case"ArrowUp":Te(r,n,f,-1),l.preventDefault();break;case"ArrowDown":Te(r,n,f,1),l.preventDefault();break}});function c(){ke(n)}n.addEventListener("change",c),n.addEventListener("blur",c),n.addEventListener("click",c),document.body.addEventListener("keydown",l=>{if(l.altKey||l.metaKey||l.shiftKey)return;let d=l.ctrlKey&&l.key==="k",f=!l.ctrlKey&&!ut()&&l.key==="/";(d||f)&&(l.preventDefault(),a())})}function at(t,e,n,r){if(!r.index||!r.data)return;t.innerHTML="",n.innerHTML="",Le+=1;let i=e.value.trim(),s;if(i){let a=i.split(" ").map(c=>c.length?`*${c}*`:"").join(" ");s=r.index.search(a).filter(({ref:c})=>{let l=r.data.rows[Number(c)].classes;return!l||!we(l)})}else s=[];if(s.length===0&&i){let a=window.translations.search_no_results_found_for_0.replace("{0}",` "${te(i)}" `);Pe(n,a);return}for(let a=0;ac.score-a.score);let o=Math.min(10,s.length);for(let a=0;a`,f=Ce(c.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(f+=` (score: ${s[a].score.toFixed(2)})`),c.parent&&(f=` ${Ce(c.parent,i)}.${f}`);let p=document.createElement("li");p.id=`tsd-search:${Le}-${a}`,p.role="option",p.ariaSelected="false",p.classList.value=c.classes??"";let v=document.createElement("a");v.tabIndex=-1,v.href=r.base+c.url,v.innerHTML=d+`${f}`,p.append(v),t.appendChild(p)}}function Te(t,e,n,r){let i;if(r===1?i=n?.nextElementSibling||t.firstElementChild:i=n?.previousElementSibling||t.lastElementChild,i!==n){if(!i||i.role!=="option"){console.error("Option missing");return}i.ariaSelected="true",i.scrollIntoView({behavior:"smooth",block:"nearest"}),e.setAttribute("aria-activedescendant",i.id),n?.setAttribute("aria-selected","false")}}function ke(t){let e=t.getAttribute("aria-activedescendant");(e?document.getElementById(e):null)?.setAttribute("aria-selected","false"),t.setAttribute("aria-activedescendant","")}function Ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(te(t.substring(s,o)),`${te(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(te(t.substring(s))),i.join("")}var lt={"&":"&","<":"<",">":">","'":"'",'"':"""};function te(t){return t.replace(/[&<>"'"]/g,e=>lt[e])}function Pe(t,e){t.innerHTML=e?`
${e}
`:""}var ct=["button","checkbox","file","hidden","image","radio","range","reset","submit"];function ut(){let t=document.activeElement;return t?t.isContentEditable||t.tagName==="TEXTAREA"||t.tagName==="SEARCH"?!0:t.tagName==="INPUT"&&!ct.includes(t.type):!1}var D="mousedown",Me="mousemove",$="mouseup",ne={x:0,y:0},Qe=!1,ce=!1,dt=!1,F=!1,Oe=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(Oe?"is-mobile":"not-mobile");Oe&&"ontouchstart"in document.documentElement&&(dt=!0,D="touchstart",Me="touchmove",$="touchend");document.addEventListener(D,t=>{ce=!0,F=!1;let e=D=="touchstart"?t.targetTouches[0]:t;ne.y=e.pageY||0,ne.x=e.pageX||0});document.addEventListener(Me,t=>{if(ce&&!F){let e=D=="touchstart"?t.targetTouches[0]:t,n=ne.x-(e.pageX||0),r=ne.y-(e.pageY||0);F=Math.sqrt(n*n+r*r)>10}});document.addEventListener($,()=>{ce=!1});document.addEventListener("click",t=>{Qe&&(t.preventDefault(),t.stopImmediatePropagation(),Qe=!1)});var re=class extends I{active;className;constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener($,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(D,n=>this.onDocumentPointerDown(n)),document.addEventListener($,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){F||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!F&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var ue=new Map,de=class{open;accordions=[];key;constructor(e,n){this.key=e,this.open=n}add(e){this.accordions.push(e),e.open=this.open,e.addEventListener("toggle",()=>{this.toggle(e.open)})}toggle(e){for(let n of this.accordions)n.open=e;S.setItem(this.key,e.toString())}},ie=class extends I{constructor(e){super(e);let n=this.el.querySelector("summary"),r=n.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)});let i=`tsd-accordion-${n.dataset.key??n.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`,s;if(ue.has(i))s=ue.get(i);else{let o=S.getItem(i),a=o?o==="true":this.el.open;s=new de(i,a),ue.set(i,s)}s.add(this.el)}};function He(t){let e=S.getItem("tsd-theme")||"os";t.value=e,Ae(e),t.addEventListener("change",()=>{S.setItem("tsd-theme",t.value),Ae(t.value)})}function Ae(t){document.documentElement.dataset.theme=t}var se;function Ne(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",Re),Re())}async function Re(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let e=await R(window.navigationData);se=document.documentElement.dataset.base,se.endsWith("/")||(se+="/"),t.innerHTML="";for(let n of e)Be(n,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function Be(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-accordion`:"tsd-accordion";let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.dataset.key=i.join("$"),o.innerHTML='',De(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let c=a.appendChild(document.createElement("ul"));c.className="tsd-nested-navigation";for(let l of t.children)Be(l,c,i)}else De(t,r,t.class)}function De(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));if(r.href=se+t.path,n&&(r.className=n),location.pathname===r.pathname&&!r.href.includes("#")&&(r.classList.add("current"),r.ariaCurrent="page"),t.kind){let i=window.translations[`kind_${t.kind}`].replaceAll('"',""");r.innerHTML=``}r.appendChild(Fe(t.text,document.createElement("span")))}else{let r=e.appendChild(document.createElement("span")),i=window.translations.folder.replaceAll('"',""");r.innerHTML=``,r.appendChild(Fe(t.text,document.createElement("span")))}}function Fe(t,e){let n=t.split(/(?<=[^A-Z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[_-])(?=[^_-])/);for(let r=0;r{let i=r.target;for(;i.parentElement&&i.parentElement.tagName!="LI";)i=i.parentElement;i.dataset.dropdown&&(i.dataset.dropdown=String(i.dataset.dropdown!=="true"))});let t=new Map,e=new Set;for(let r of document.querySelectorAll(".tsd-full-hierarchy [data-refl]")){let i=r.querySelector("ul");t.has(r.dataset.refl)?e.add(r.dataset.refl):i&&t.set(r.dataset.refl,i)}for(let r of e)n(r);function n(r){let i=t.get(r).cloneNode(!0);i.querySelectorAll("[id]").forEach(s=>{s.removeAttribute("id")}),i.querySelectorAll("[data-dropdown]").forEach(s=>{s.dataset.dropdown="false"});for(let s of document.querySelectorAll(`[data-refl="${r}"]`)){let o=gt(),a=s.querySelector("ul");s.insertBefore(o,a),o.dataset.dropdown=String(!!a),a||s.appendChild(i.cloneNode(!0))}}}function pt(){let t=document.getElementById("tsd-hierarchy-script");t&&(t.addEventListener("load",Ve),Ve())}async function Ve(){let t=document.querySelector(".tsd-panel.tsd-hierarchy:has(h4 a)");if(!t||!window.hierarchyData)return;let e=+t.dataset.refl,n=await R(window.hierarchyData),r=t.querySelector("ul"),i=document.createElement("ul");if(i.classList.add("tsd-hierarchy"),ft(i,n,e),r.querySelectorAll("li").length==i.querySelectorAll("li").length)return;let s=document.createElement("span");s.classList.add("tsd-hierarchy-toggle"),s.textContent=window.translations.hierarchy_expand,t.querySelector("h4 a")?.insertAdjacentElement("afterend",s),s.insertAdjacentText("beforebegin",", "),s.addEventListener("click",()=>{s.textContent===window.translations.hierarchy_expand?(r.insertAdjacentElement("afterend",i),r.remove(),s.textContent=window.translations.hierarchy_collapse):(i.insertAdjacentElement("afterend",r),i.remove(),s.textContent=window.translations.hierarchy_expand)})}function ft(t,e,n){let r=e.roots.filter(i=>mt(e,i,n));for(let i of r)t.appendChild(je(e,i,n))}function je(t,e,n,r=new Set){if(r.has(e))return;r.add(e);let i=t.reflections[e],s=document.createElement("li");if(s.classList.add("tsd-hierarchy-item"),e===n){let o=s.appendChild(document.createElement("span"));o.textContent=i.name,o.classList.add("tsd-hierarchy-target")}else{for(let a of i.uniqueNameParents||[]){let c=t.reflections[a],l=s.appendChild(document.createElement("a"));l.textContent=c.name,l.href=oe+c.url,l.className=c.class+" tsd-signature-type",s.append(document.createTextNode("."))}let o=s.appendChild(document.createElement("a"));o.textContent=t.reflections[e].name,o.href=oe+i.url,o.className=i.class+" tsd-signature-type"}if(i.children){let o=s.appendChild(document.createElement("ul"));o.classList.add("tsd-hierarchy");for(let a of i.children){let c=je(t,a,n,r);c&&o.appendChild(c)}}return r.delete(e),s}function mt(t,e,n){if(e===n)return!0;let r=new Set,i=[t.reflections[e]];for(;i.length;){let s=i.pop();if(!r.has(s)){r.add(s);for(let o of s.children||[]){if(o===n)return!0;i.push(t.reflections[o])}}}return!1}function gt(){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("width","20"),t.setAttribute("height","20"),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.innerHTML='',t}X(re,"a[data-toggle]");X(ie,".tsd-accordion");X(ee,".tsd-filter-item input[type=checkbox]");var qe=document.getElementById("tsd-theme");qe&&He(qe);var yt=new Z;Object.defineProperty(window,"app",{value:yt});_e();Ne();$e();"virtualKeyboard"in navigator&&(navigator.virtualKeyboard.overlaysContent=!0);})(); /*! Bundled license information: diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js index c254055f..dbeda68e 100644 --- a/docs/assets/navigation.js +++ b/docs/assets/navigation.js @@ -1 +1 @@ -window.navigationData = "eJylnE1z2zYQhv+Lzpk6lpu0zc2Wk0lSKdJYsnPo9ACRsISaBBQQdOrp5L93IOqDJBa7C+bKffdZ7C4/IBDUX/+NnPzXjd6NpmYzlc+yGL0a7YTbjt6NpK7L6uJ4/JetK73xSel89O73H69OnsvvymXbG+Nupu9nJg8RgSCB9cEqqfPi5YsoJcltixNisNhMJl4AIvvr/FlapyqlN2dEVoiqktVFy9glXI7bjPfWGnvvVFGFiLMNIyyEFaV00k62MnuSNuT0FRitXciQ1LbSlLVxt/JZZTIGOglYI5rvpL5efEJGdVBgtAdRqFw4ZXSk6D0BxvpqrpVd1FY9KqjsHTObsxLrAihYqMGJN4XS+UoVDkKdjASjLtage12scc+JVIXSm6nabMEBtO0EyWgnMhjSmAj/2jqhNOjfmHD/j0LnkLM/TnjW6zHoWa/HpOdVxPOK8iwV7Fkq2jMy3FIR4/00X0pdGbv6CAHOVpzyp3zZCbDWjQX3nkrxBPn647jnoqg3M6XV5wXkf7byKPdLjHK/JChWVlJDN8yzDSfcyUK8NDfES4jStvNJixnFWswoWmkcmFdjwb2x84t3dh1Vi6IGbvpdO5NkDQqyhs2ZzMFLr6sgaKWwbmoy8CI4GZmMWGotO0FyVu1AhDdgvu07gNJO2keRyeqif/mP37wFJmKylNrdCidARqDCkGuTv4AUb6AcJ1uhNzLq3pgxyGQrbAX67y2oqymM3T9Yl9L6uZXP9EZU8HCiaixELgvp5Fe53hrzdCerndERPKjE0d35YocVzhQh56mqHALwZhoCF/9go92XTrgaYzQCLuhOfqslmlVHR2MPHUGABwUb5Sdj/jBJPAgx8P53z3z9j8xgXsuOYZR+tMLKvHnARE+LUIZCLXKKHo0YwN8//QXWut5AFqDDsF/MupCrl13kzD2bMcj+hyIMaEyo82GOw7ntRLQYfldXW+w6aNlpDHLLagu4oJvYw6IvwoDfamlfODdVSIiB7+oCBnkD5kidosxTs5Ku3nESg4To+FqrEf2FhvYwAxkLusyE1u3f9RDyIMKAK1nupBWutpJzacTlWJB6lwveIxlUYuiD9FY6oQoQ2VFgqO/HqPHLuCvBYAJae3H+FnchYusu49d//Hb5ZgxTFrPxm9jTLOCG4oRI4IUVhIhfXii7N/UIsdDUAyP2VqQCILAaRfOSih3xSI3JK3tfmhyFakBLlcp+mE8o8MN8MoDKG/RJOCBCWrMDh9SIaeEGx8IbktYLThuGdCCl+D9Td3aQtAhr4Zy0LxNls7oQztgPQvfhkGYIF7lDEPJB0cBux5VDYuBNoT2omKc5FVI6SEPmEr6/OAwZfneBELCmAho+F25f18ymEY2CZSTdhCTD8cJqZpKqZWJ1MtwKGao2fQFFzMC3Uw0si76ZwjmdJdMQFayYkjSkA3FlagywM6AokYx3DBWnRGIWaWCF6PKk14ZfmMSq0A8WQJJEJYY+/BmS+UXo7svmA/NoYBOwEwLQ8LlwRbtmNo2oJCyj6WUpdO4X+ULiyURT9i/Vm1dPIadlTCKhfYF1afxIfwJJEpXqU1RKRunvSjgQoR0JUe+riPsV1x9rSijhUomigSommx5w+ngjZ07byCSxEk/L+7Ewxk4KKbTSmzvj50yXr/tkUDSIDNcCkQ6KgteJ4UJF3XZ23jTYbbDrBvZDTrGemUUDC3q2cBh4uUIFg4ld+T0zTStVDi7Cni18Bl5+SJXCjjSjJ0ggUq2JCPkRWOUYVA2qGKm14JYirRKfdO7vBqLsA08GiqCOQmkFPsa4korx1Nu51vCegF1rMd9b6WTm0GlSVMiLsDJ1toWZe1MCBS9jVMiLwIGncYvOpqiGUwR7oWA/4Fd9Ae1/inojDQ0VXCZ46XaMTBJebFDEIRNJJ2YcT5efK51oWpYzkV3nuZVVMK6zhWLsd+T33fcHWZ7djYwt73AHI0JAWgVp+FywaT0zm4a3LyLj0cML/Hic6z+ZY7MWWJXCRirZEiQQOdUEhNwIjGIMqARehrQa8AowIHsq9dS8kaQTMmakm5ir8Z/HwEtEbVsKBysdLEuiw4UMFClMoqxRJRXDaNHeqNwH98w0LVdVZp7DR83ZQjJq56fGM+iB1balcJB+R2RJdLDfoSKFifc7rqRi7IR2qnDAj5yzhc8YB3Pdto3BWTVaPNuYjuQX9SZgFfWG4+f3i0K+/jjX//MCOe9AEZ9MVCyi4/LhM7pr5bLul4wqdER8Mq8KfR2HH68AP3t6dInjOnyTBT8Lu9Y0FtahmDAxAlxPQJPGJWqMaKk4tvW9WQQPSFKoixmDexKlkZGORoWJEcCOQpoULnPcA0dNj5k74u73hUdO+G1hzBfNsycgif69xYPI6rrcv8qQdnkZQAHNEC60EBDTDeVHuoSqh8bC7x88ryGx+TkOzy89t5/OCzmrMTEVqfIfcoI7qM4WPgMZJShKIINd7dv5PLyDMR3F/y6ctP5T9eP6fh8cCJKJSIkxbXocsOARWTIdLz8hp3/9xP5J5VlY5feJ+18+2H+pXLVxtW3/v8gZ4Y9jbvsPdPwHP/d307P/Y60zv6Rw/ILnIOiC3v764+//ARTOvvM=" \ No newline at end of file +window.navigationData = "eJyVmk1z2zYQhv+Lzpnakpu0zc2S7ViNZKumYx06PUDkWsKYBFQQdKvp5L93IOoDIIHdzVXvs4+xAAnSkP78b2DhXzv4PJjp9QzeoRx8GGyF3Qw+D0A1VX1x/Pynja1c+CZVMfj86/cPp8rsH2nzzVjb8ex2rou+ogf8gOtBVED6HJR2Xi+mt8Zoc9bkpahrqC+OSVg7HHWqH7S9fheyFKsS0qYehVnHs9uJVgpyK7Xq64KY8DBGF6MIa5YLpSDuOmSYYaKrSqjiTsgSisSo+gxuPM7Hs6xANzZpjXGY+QbeZQ5zocQ61nAQ054Hbe90o1JNRyDa+fgOxsgCMiss3DRGqjV29TCK0L8p61y/g9mlWghyzPS4BXW9mE5KCcr2RUGMeTL4uwGVQ9tYXxTmqOm4dUQkx4hVnxxKCLBciXkOc8z0IkpZCLeuCVUHwFxLfT29b1Z9xyEgaqVZNEa+ytidFMRsz2I++ki4HML2PbstkBDuGcJo7J0JHk6e6ZDhhnEpVfEsy8i16IWEoymjS+U+xysnQhUlLIWpwMxEtY1ZugxhBFlKtZ7J9Sbakp8TJmnyphRWmzsR2d86AOEqZSUsLITyX0w8lZcTJq2syOOttRFR3xgrZLyfNsLr70qtk0t1CnHHF2HEGm60Nm7zjd+kXQY33gtVxCzuc6KyWY2ilc1qRFZeJSqvyMq5VHIurI03HwCUq5JxRSXpykTrlSR6nz5moGptnu9jgnOKW77Cbiui69YmnOoXWUdfP8Kcb1oYTckWRuO+GYi3mMR9jlcuhHLb7URUi7Kpr77GLF2GMJbN2l1Lvy+irlPKs3zLMMu3jLAYqN0bUtRxyHDDE5Ri176SDGMWP+ebFnPKtZizbSPSNqJtlbbRWWoTTvVS2k2WG4DovdFlCOOX8XSSesifQobjAbRaSgNPegvJJ3ScZNiXS/Th1GVYxswaucWH6kOEU5clmGwjivjinmPcg+29vJ33SLkdBLO4nGmK75tezPZMHqOPpZAgbJUwdqbz6DZ8CpmOmYzfjAHAdKWmycv5pqW8iz77uwzTmH6UdpAf8lEdM5+pe/55A6bStRX2SRTSvXkn1X2U8Lt7OGpzAaN2f/9HXwi9GPe8iLxpqpiiTTjVX4eXqZs6ALiu+Or5Od800dWK1O0hnnNIdTpkdzq6RDyjS44jGyKObMhzYOPIqHEshQVzAxbyxJ0RAOh58/kU4nBA6s2zVBbMq8jdiXOfC7Wjj5/i2gyMO5q6EVZQZg/lyq2wDTnilkKVi+mhrSd3uFfbuLJLcZX1VqsaSGeLEdLuUWDoip0DJhTY3IUModsf8lFNBhAhpFwczXh2e128g7Gyhio4D/ZcXYgQum8iHrfuXDM+bSFCyYj7IkRQ2fHwDr2DexRLSY4yAvLE6auvw6A6TTStee1qulHNblGjzWlOW025wvvyAEpEdhYypA7p7RRjEv9gFm0yBnLFVNMJlq1PT0IfQ6Wnvb8p43tUQOCq/akw2XkP40iRfn0CVbWnzviShwxDd/uvBVVAMVWvGlP6HENLzmIP40iRWfQJTNU+l5PdnmNaMpO1RR+1fYyWIj1yXylO3/hiz9ouhAnvG3ITDBFKlu7xlOKKShb0O3cf40npXiMkU411HkKYsD1kR2Q+gIncQTvVbochdelRnWNUovM3dF19gBKRzYUMqUOaO8WYZA6WvsC6EC1MD8vLUY12uwA5sC7FUCJD8wBM5L41QS8IH6BEVIsdhtSl2zvHqOTwdQ45rj7H0iLjCxBM5n0lg65DhGNqqe7jKFeenoMehSvdd0Go7QxgoiwHRb899ChU6Y5O0cUJCFJFLUgXooXpafNyVHP8gdVEq1e5jqtCBtO1R4XolIUILUN69AFMtITVRus3pMWAYKhuwApZxkcVIgzZHw2YHXrVxkCGOAPbbDniACT+8zr+snS39ZR2tw1/d7rbdj2Xv/0y/Djyd9PNrpa5KNs38JivT1DOF2lsgyl7AGVsjL/M78JI97u4+sJ9HtZeBWXbQlgYixq+Pc3O9a+N2s9PfREAoejTz9//+h/mRebr" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js index d672b4de..393d5228 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = "eJy0vVuT5DZy/v1dZm7nLxfOgO5Ws7v22tJqQof1hcKhqO7mzJTVXdWug2S9G/7ubxRBVpHJB0kApK40aoLIp8gkkJk/gPznm+Pht9ObL3/655tfdvunN1/6d2/225fmzZdvvj58+rr5tXl+8+7N5fj85ss3zf7ycvqX/s9ffD6/XI89Pm9Pp+b05ss3b/7vXd+LsLdu/vyXr378V66Pt0/Nw+XTuKd3b163x2Z/HspI9/6X77779rt5E83xeDgusfP9j+/f/+X77+ctnS6Pj83ptMTWf/7pu7/PG/pte9xXWpm/aEuu19/+/tdv2c53+4+Hyr5zbsOyOzB78Uuv+/2p+v633fnx81eH81df/+Wbw9Pk8Zocz33O/rQ7frgcdx93zTGry7fb3fH1fgL+KVO1c7Z/2D48N8UCzt1Zi1R89bzbP/2wez7nmX+4Nj/H5svsHnItHhbbet/snnf7T1/vPn3ONPoYz3juzljN+ofjoVzA6zH90OdqODwfjl9dnh8yrV+bP8TmC+3uz9vH8/fN/nTIfMIe4ymn/pRl9i/H83a3z7R8a7yGTVVkVC21+m+XB5ln8XNsudRa5u/7HFsutPayeyoYpD8P269kOfviDk9YZPs/mt9ft095Zn/p2y6y+HWz/SXP3nNsucza4THXWmy52Fr26Hs1uMKo+01zznXZl67pcnsfni+nApuvsfkKdnMvbjS70tX9cDy8/zbz2ewNPx4WP5vfHM67w75kWntpz1hnVvv2cn46HI4F7nWIZ6ziZR+eL5++2e13//4hz/br8+XTy26/++/XtSz/SNOYGcvLPfzDsTk1+8em5I6/duesc8+/a563v8e2Is/+8XrG6XbGatY/fFNu//VluYKXwzkzRzr2bRdZ/P583L0W5Ayna/tVMoYf97/sD79lRq2XW+Nym0yG/dfjrtk/Pf/+9+vxGSHDtn9A5j3pvi4LH/2iOU0fvpE/m0XCXl9iD3+Euqx6AauusHZQrm75BWwl/uFX8R/fvl+u8tfD4x+kcam8lZV9tT2fm+Pv73fHx8vz9nw4/nU7O0xN9T3EXh5vvXzcFoxfGSpza1pAWnl9K0PPfK0LKCmpe81rKKmBTcXU1cPKVGUkELywopwiQ9syJ//DvDu7lgc0ldf1cvQU1PiQpqp6X4auvNofUFRaB8zWMlszS4opqKHNq8mpFU6VlNUNs1RUXI+yemKOitzaItJSXmcsUVR1kyrqj/Oa8mqRUzmldcl5JTk1yqmOsnplhoqM2iVQUVTHzFNRNWsW1zfntWQVo6ZKCitSmTpyaqAJLWX10Fw9NTepvE6aryajZpoWVFQ/zdBUUEsFoqrqqvOqSmqsU1V19dZ5VX0FtFxRXwtdVU1RVRRoqqyQzisrqZZOddVVTstUzVdReV0lFdUcZTnVVaSorNI6ryS/6jpVU1OBnVeUWY2dyimuzCa0MFXanOrsH1SVXViNXa/OuUZ9c4Va0qIa0qLaUWXNaJ1a0dIa0Wq1oRVqQivUXBbVWlaqsSyurSyuqSyopSyvoSypnSyrmdTWSpbVSGprI2vURJbVQlapgSysfSytedTXOpbVOGprG8tqGrW1jMU1jAW1i4U1i+paxQo1ikW1ieU1iSW1iFVqEAtrD+vUHJbWGtapMSytLSyvKSypJaxVQ1heO1inZrC0VrBWjWB5bWBpTaC+FrBGDWBZ7r8451+Q68/n+G2zlIL24IpZ/b2/snQ+ilyUx2PTmQk8Y79krcpAQ93iFE7HXAVhaDy/dMBZTNcMhrZyigWMlZwqwcBcWXkg0y4TxCRMZwUxnPVCd1rPj2ZrEEOr+cUH1mJG1WFktajcwFnm6wxDm7kFhnlryUx7ai4jzWbscbWEga28IgJvJ+c35ZUNeDtcADk2lRc48ta43GlsLS9lYq3N1UJGBvOLIFk289ykoOzBWP3b/ppWvN++ZNjctW0ftxmBJmPxP8Qmw9YvbatFVvKmiV/EZunswNeMhrYyi0Wztn44XB4/Zxs8d63rrXJVooG5vPLQjJ2825ZdEGKssSn4wFZm0j1n6Tp+pbdPUXvXMSxn81SO1fTWKWR14dg5V2eamFzjLvKVJWAyq6TEWc2oJQ3NFhWRGLs51aOB3bKyEWP3w3Z/zWbyJorX7f6aziydKe425X8UWZXLRqFrbSzH3jPzLp5cO/yeSmItd0Nlhs2sIaFkKyVnM6vaN7RbWOZjbOfU9waWywp7mXbTFb2E5ZxSHmubq+GNbOYV7zhbh4fD+R/bx8vl5f1zs903x++zrvP1tF/b0x7jaaeF1xvoyIkzkZBlkSdSkpm6IDGLc5n5uupAQUlBlbH54373a3M8bZ+zXfHSn7GCT87UcUdWMwu4jLX/3J6b45+bc/N4zhrcfru2f7q3X2D58P1vTfOaFQj8djjd2q5gMTPzv1mtzP/lvUL+p6dfm+N5d9rt73Nz192/DI6x1XEj5K2/x8P+dD5eRjct1d/bcWP8K4YC7yblRt9/w+v2eGrmrfXNltn5vjn+unts/rw9bzNNnuIZT/GMEuvDG/WX67vwfjzvnk8Ts/dDq9wm0l3WXRqoS1y8x2OzPTfvDy8v2/3TX7oX+80Ybk95jKfw7wLMt7/fN4/XpKFMQn/WOip+2L00h8u5RMI5nrLU/m+78+fO+qzha9vzrW2BxaHbftget22a9P5z8/hLM/25tAHrwtJKofWt8wZeQNjjzLskJzJT9+96ONNi33aZxd3pT8fj9vdMm7vTtmu91OpXh8M1Vsq2+3Brv9TyX58P26l3pux+7Fovtfq3/bn5lOufb68jdd9+qeVvH/67ecz/wYe++VK73782j9dS91O26dPgjMXWz0cUcyRN982L7Q5Ho+HKgYnp4cFVJtJJh1lT6Ujj4Gds5H3g2x+GawDS9vp2Cy39bb8777bPu/8P+ErC6G50Sr39w37bhUbNy/WsefPTM5ZYf9qdHg+/gnEBGR40LrI5ejQKLK5i7/kwfQqnpmKreiun8/Z4/v4RTChTW23b02Pmmx7SFg+v2QYPr4vt/bp93j1tzzmP5aBpvb3ftrucx6FrVvYMTIbMh8P5z801i0lYvB1fceAc91kwdt7FJiPH7dPTMb6dO8PyvfFCq/c84vtz2lOmv7s76XSe95kMFR/R28hYCf0Z+3jGQvu71CRCrO7mZo4MWy+jdX+sub7pGhbzL23bfJ3reth32e2/bfdPz8kJhAg47DsH+3w7a7GOP1/npRopT7cTF6gZ5WuxeJD7pPWNF9psf0HR073U5v3C5ZkdtV9u+dfm2NXFMofU/qzT/axFKj415/eft8ft47k57k7n3WOmjk/N+XFy3lIlsUH+GPCpOT+1/1s7Dowyq/25Oe63z+9L3KE/aSWfSIeUxO58VDlr61R+vU9rXu/L/nR5OD0edw/NX4+Hl78fzruP02oN1DE49ePx8LLvTy3VAzPcb1+b/Z8+/C0dIXYN1s10h52WZbu93kQm9lvz8Plw+OUvvzb789e707nZcxnSSEZ3anM99fl+arEeOsifj4dnNigG1+N6zlN/zjIFT81zc27+M/64TAXxnN9u5yxTcBvqUoMtNX8b6DLQa67tayR9KRfQn7VMxak5X17LbkF7yoI7MHzY/xHzyN1hj8EQOb7Ko476zHrSqdiZNPqry8eP4BGH5vtzHvpzVlHwl/3lpcx+E89Yxfo328c/JZJUVsPL9nEuXy1U8qE5Pjb78/bTdJxjlbwOz1tFyXfbfamIY3fKOvb/9atC65/Sm0YKbSfq5az5maJ5WsFwkPnPA9ry1tsfHV1lgJn2mDW8jGUWF36AVfQYnU9P/293+n+7/efmuDu3te1SBXNFIPz7kyWgFRSxBSEgJ1kOWkELKA4BBaQ0tIJdXCgCpqdlorWs515+XDJaQcVsAQmIYctHq2iaLyZBWXwpqUpZTmEJPr3TstIK9nF6nx491rXPFJyAhES5aR0VXPEppSVVelqsKKMQBTTNlKHWUMUUSbCgRIlksZa5AhUa7pny1GI9qFgFNNBS1WK7h9fmuD03ZcHV2+6snPcKZKngy2dAQLp4tviKnJp2qWqmipfYdNlv//61AWsasMFT13aBxfPluP/248ccg9emh7bpUntTAp4ylwbgWdbySqHA+HwhdLFvza7dBbKyV++mFCTTqPE7PKCEtsn6CdW92/KsKqpelloN7C/Kr2a0FCVZ42uyPNOa0Zafbg2ELc+5ZlTNJV4DLbXZ14yCjBRsIGJBHpajo+jmLMzIZvSUpWUDWevkZrPqChO0kcCVsrSJxuJUbTQGLMjXZpRkhLzT0egPUJKbvg3ELM3h5vVkJ3JU1eJsjtVWmtIN1K2V183pyw3hx9KWxvGsqqI0bzi5rJHrscpmE76Bmuqsj1UwTf2KAkKQBPJveMtXVpAODvSskBPOqZpPDMd68rPDOcsZKeLYdEGeyNrOShYHposyxnnLM2kjNZyZO7J2KxLIgYwVs0hWZVkqORBYl09SLeOkcvpCxLuK27GV0shxf5n5411gReJILJZnjBnW51PF6e+uzBEz1Mwkh0RKZVaYoQOmg8R6UR6YYTOVABKzpZlfruW8S16T62UoyEjyiJAF2V2Wnpy0biJpST4HVY3Sp+cD2Oc/fT67ZkUj0sTOn4evuuBtPXHvusi19+NrprVL+k1FObaSyfBklCvNgjNsp1IBPMKuaZtNeIn5qkw3TwGf4iIddbntrJpPzfmr7Wn3+Lf9x8O8kk/N+eHaehdbV3tfVio9tV2fQ+coYhOeqZiqTCdHx4fDaXeNKrJUvN4bV9+N+RSdTvjVufmsFpyUE/tl2fiszcNrk3Gxu1bVV/l1e8mZtfpm1XaOl/0Phw+HjCfqeNmfD6+H9ALRDGtzhQJisrZCMKsjN2Ukepbmihl3fTZJnDhAdnaIrJO0cPhq84HJy/PDWslg31VuHnhVVJMC3uxUZH+szYzEb/gba3M+VsNcuncTUJvpsdZxknezWZbfsZaSqd3NWHFWN29v9qJW5XKs3Zw07mZ+SQY3oyIreRsIWZS3ES2Z6cbg2SrONFiLyWCGPs0rWeRTi5vRuqxizu5MQjG2XplLMBryAvqbimWxPK+DD0eGEuoiEcZ6RiB9H1TrY2hGQSJ8vlktjJwZS8dm+zQ/X15b8a+r4K2cmvNXx+v7UvdzUcGpOT8MW1Zaaz8I80Pz0pK1y5H/dafm3H4U5jxqX2k502+rI2jeOtrSRMxym5j4/tME625gnlrNWoBJ3NgAm8Ex/WenFzdzizMLRk1OUnETUpJPjG2OUwn4aaq7weHhlVKLSZeZKcZIaUWqMbVbnnLkaZhPPeA1qExB8jTNpCJTQZUpSZ4amJpMNRSlKHmWU6nK1HhpylJgP/sm1KQweToyUpmpnAUpTa6qnNQGCVuS4qS05aU66FkuTXnyFKTCz+RosrICNhWaiqhKibJ18KlRQk1dipSjKStVmqpalDJl6mJDUCipKhTNUTOfSoFJoDqlylGEU6upirIUK8dyt8yvNADrlwdmfSQ0TwmX9E3t5yR/OVbnksCp5dxkMNN6RlIINRQkh5lKCp/Q2mQxUw1OGqEMPnnMtJfvetfllyt4XjpxnZqcT2CzLaJENmGQS2hz7OUmtlPzSxPcHHUZie5UWEHCW6Ph5+HH90p0/Mx9ii+phSTh8WvAyH48slbqPegtN+vupNUk3ENrFbn2nOWMNJv83toMe07JXHI9lFGbV89pwCn10HJZNj1nL5lID00W59BZVnMuc1XmPGc9J2keiliSL89ryUqVx3IWZclTRZkJ8vgpLM6N5+wmUwnw9K9nl0+Gh6br8uAM6zMp8ERDZfbLK8lLfIdaluW8s2r4YJoIqYujeQ0ZSe5oWK7Pb3kdidR2aLswq+XtzSYyQ8vVOQyvITvwHWpZHPPymnLC3aGckkh3YpkElpfjebuDiUc8slZgOegtN7DspNUElkNrFYHlnOWMwJL83trAck7JXGA5lFEbWM5pwIHl0HJZYDlnLxlYDk0WB5ZZVnMuc1VgOWc9J7AcilgSWM5ryQosx3IWBZZTRTn7gsbP4MyuoDkb6eB1/KQXB69zdpMhAhhh1rPLB69D03XBa4b1meB1oqEyeOWV5AWvQy3LgtdZNXwARYTUBVC8hozgdTT01wevvI5E8Dq0XRi88vYSu0XGwxy/V2TeQst7skKyG+W5ta60mtqfMjI2tztlxgazN2VkJmNnyoyl2RRjaK46xeA1ZKcYQy2LU4y5uzyfYoxveH6KMbE8TjH+Dc+b1z+vlFzcusrMLFpFFWnF3U55TsHbnE8oRr+xMpvgNcykEncBlXkEbx0mEXebRRkEbymVPtyNleYOGfZmL2pN1sDbzUgZ7uYX5AtzKnKShaGQJZkC1ZIXwg+frdL4nbeYCpEmT/NKFtmw/W60KmaftcsH7MR6XbTOasBvbBjY5d/TwPWdlQbcLS3KAWZ0sOHNSEJVbMNZnw/9BwN2ddzPKcBB/91qWcTPWXqdjQFe2Y/s8L3Phal3K7UxKmc9vbzlbnd+WcusBf5pnF3GwvWfG2LfzS2Nr1k16N0tA9PcG1tYH5wP2gfumB+xE5skXL88SGTo8iDXCtf7rnLD9auimnD9ZqciXGdtZoTrw99YG66zGubC9ZuA2nCdtY7D9ZvNsnCdtZQM12/GisP1eXuzF7UqXGft5oTrN/NLwvUZFVnh+kDIonCdaMkM1wfPVnG4zlpMhjX0aV7JIh+u34zWhetzdmfC9bH1ynCd0ZAXUt9ULAupeR18KDaUUBeKMdYzQur7oFofUjMKEiH1zWphSM1Ymg16bzarg17GenbIeFOxOGRk1OSEdjchJaHd2OYktFPYkFovtFOFoZ2qDO3UgtCOsZkV2qkVQjtGw3xop5aGdoz1VGin6kI7xhIT2qnq0G7O3uxFrQztGLt5oZ1aI7RjVWSGdmql0E5VhXZqQWjHWGSmV7UgtEtanAvt1LLQjrc7G9qpNUK7pIbc0E6tE9pxOuYCDrU4tEtazwrt1AqhXVJBMrRTlaFd0lJGaKcWh3ZJ6wWhnVottEuqyQvtVE1op5jQ7mUHDb3sVgvtuq6yQ7uXXV1o19upCe04mzmh3eA3Vod2nIbZ0K4XUB3acdYToV1vszC04yylQ7veWHloN2tv9qLWhXac3azQrje/KLTjVeSFdnchy0K7sZbc0O7+bJWHdpzF9PRKnuaVLD41j8dmCxfN3U0OGuWOkAXh481KXfg4Y3cufBxZrw0f0xoyw8dexcLwkdUxE9QMJFQGNWnru32Glw0a1XhZToh6N1UfoqYVpELU3mppiJq29NocH5v9efuJv6KjZjXX9NSc/3Q5HxIfLLsbOjXn7eV8mPlQ2YylTP+sD7pZ699s95ftc84vfWlbLvitzJKFm52MJQtzFuCShbEBdskC039+ktKbW56kME9DTpJyeyZKkpSRzWmSgtcWvOzWW1zQ91WQp1QuL7hZqstUFi4wGP7OBbnKkiUGNwkLspXyRQY3q8X5StUyg5u5moyleqHB2Oq61zUzaVljrcGMjty0ZaXVBkRNfuKyYL0Ba5MLuxasOGBsziQvsih7qV3YcLdTm78sW9owtl+fwSxd3HDTsTiHWbC8YSiiOkpkFjjk+FtmHrNoGcXA2JJMpnghxc1ueS6TXj4wl8zIwmyGW7Qxk87I0nxmwQKRobX1fTUnpZHlOU3SHp/UyJKshreRSmtkQV6zwsKam8E1MptlS2vuT0hZbpNeXPO3b79v9qfD8Yd/AwbvB1dKc0iHmbnOQGNFwkNtlmc9OfbnUx/w2yvznxw9M0kQFVOZCeUogekQtV+UE+VYTSVG1HBpdpRtO/PC1+RJORoykiUqZUHGlKcoJ22ailqSO2FdeQnU9HktzaJyrKcCv8Rosap1Nt2hAqpynkwNfOIDldRlP/N6slIgqmhRHpSliQ0wgZyqKHNeyXzCMhnYq7OWeTU4daEKyvKXeatz4T61XxvzzyvJDWGpoqVx7LyyjGCWiiqIaKH9cVj7H83vr1s0qscDK4Wzg84yQ9lOV0UYO7RVHsLO2Z0PX8lvrQxd53TMhK1DEZUh65wCGK4O7RaFqnPWUmHq0GBpiJplM+MC14Smc7YzwtKhhAUh6bySnHB0LGZJKDrVkxeGjp+70hB0zmpqGgdP+2pW2bBzaLgq5MywzYebEwV1oSavIyvMHCpZFGLOamEDGiKjKpjhFcyHlaMBuDqk5FXgcHJouSyU5K3NhZFDu7UhJK8gN3wcKlkaOvKKMsLGoZiCkHFidxwuft1sfwHGrn9eKVS8dZUZKLaKKsLEu53yIJG3OR8ijn5jZYDIa5gJD+8CKoND3joMDe82iwJD3lIqLLwbKw0KM+zNXtSagJC3mxEO3s0vCAbnVOSEgkMhSwJBqiUvDBw+W6VBIG8xNeVOnuaVLLLh391oVfA3a5cP/Yj1usCP05AV9t1VLAr6ZnSwwcdIQlXowVmfD/cGg2p1sMcpwKHe3WpZoMdZmgvz7jZrgzzOem6Id1exNMDj1GSEd3chBcEdsTkO7T48Xz59s9vv/v0DMHc/uFKYRzrMDPYGGitCPmqzPPDLsT8f/oHfXhkE5uiZCQWpmMqAMEcJDAup/aLgMMdqKkSkhksDxWzbmRe+JmjM0ZAROlIpCwLIPEU5YeRU1JJgEuvKCymnz2tpYJljPTXFJ0aLVa2zoSYVUBVwZmrgw06opC74nNeTFYJSRYsC0SxNbJAE5FSFSvNK5kPTycBeHaDOq8FhKlVQFqzOW+0+0XFtmDN+xdavsXVZhDP62AbzsXZqM+dT7fMW50JzarU2QJ9Xcj58+vScI+HWsP5Xp1fvTozNLuHNtIbW8UJj3GLeeVu5yQ41vTTlmVeWkfhQUQXpD7SPk6Afv2dM//j9yklQ12FhEvTj90uSoN5mfRLE2c9Pgga/fWESxOnJTIJ6MQuTIE4JmwT19quSIM7qXBLUG65NgmZtZ174JUkQp6EgCeqlrJAE8YpKkqC7qDWSoLGusiTo/rzWJkGc9blgkowWq1rPSoJ6AYuSoBkNeUnQSMmyJCitpygJ6hWtkgSxmrLC0YGcReFoWkl+EnQb2BcnQWk1fBLUK6hLgtJW85Kg2/hVlASlreYkQb3NkiQobTE3CeqtLk2C0kpmk6BeQnYSxNiaTYJuxrKToBlrXBI0MpaTBKVtlSZBvem1kqC0soIkqBdVkQSN7JMk6Nicmv0jdLHu0FoJ0LC73PSnV1eT/IzsVaQ+s7YzEh/6m2vTnlktc0nPSEhtyjOrAic8I9tl6c6sxWSyMzJanOrk2c262FVpzqz9nCRnJGNJipOhJivBIYIWpTdAU2ZyQ57J4tRm1nIyQESjwYqW+aRmZLwupcmxP5PQTFVUpjMzWvKSmZGaZanMvB4+pKRS6gLKGRUZScx4sK5PYWaUJBKYkfXC9GXG4mxQP7JdHdLPqMgORUdqFgeiM6ramLJvFPcRzgSlI3nt6a/dn07t6ZkBao6uYiXVtseh8XfN8/b373/bnR8/C2B4eHilEHnSZWaYPFJaESpP7ZaHy3ka5kNmeA0qw+Y8TTOh81RQZficpwaG0FMNRWF0nuVUKD01XhpOF9jPvgk1YXWejozQeipnQXidqyonxEbCloTZKW15oTZ6lkvD7TwFqXAmOZqsrIANvaciqsLvbB18CJ5QUxeG52jKCsWnqhaF45m62IAQSqoKCnPUzIfmYBKoDs9zFOEQfaqiLEzPsTwXqk811IbrOWrSdfGpjvnKeLZFVBtPGOSq4zn2cpOSqfmliUmOuowkYCqsIBFIaEgnAx++mZHw4Zs/ICHoOq1ICT58szQp6G0vSws4HWWJweBarJAacLoKkoNe1ArpAadoNkHodVSnCJz1nCShF7AkTZjVUHBDlqYKnJbCZKGXtFK6wCsrTRju4tZKGcb6ypOG+3O+JG3gVOQEW2S0WV1FdvLQC1mcPsxoyU8gRoqWpxBpXcVJRK9stTSC1ZYdrg5kLQ5Y04rKkonbhLFKOpFWNZ9Q9ErqU4q09ZKkotexRlqRVpSXWPRaylKLGatzycXIaG56kbZZk2D0EtZMMdIKC5OMXlxlmjHSQRONl0Mi/r0eWC2xuHWWnVC0uqoSibutmgSCt5uTOIx+a3XCwOuYTRTuIqoTBF5BIjG42y1MCHhr6UTgbrA8AciwmXGB6wJ+3nZWoH+XsCjAn1OSF9gPxSwL6Kme3EB++NyVB/C81XRgM3naV7M6E6jfDVcG6LO25wJzoqA2IOd0ZAbidyULA/AZLTMh3UhGZSjHKcgJtAcD8IIAm1ORCqzvlksDas7afCB9t1sfQHMK8sPJu5LlYSSnKCt8vIspChuJ3XG4yHyoZuXP1NR8pGbJJ2qWfqBmjc/TrPVxmsWfplnlwzSVn6VZ8FGa+k/SLPsgzbLP0Sz/GM0qn6JZ7UM0a32GZs2P0NR/gmbpB2jqPz+z9OMziz49s8KHZ1b47MxqH51Z5ZMzK35wZunnZtb52MzyT82s9aGZus/MLPnIzNJPzKzzgZm1Pi+z7sdlVvi0TPWHZWY/K9M3+PB84R7S6+GVQ9Fbl4XhaKt0QUh6t1sflvIa8kPT0TVYGJ7ymjJD1LughWEqr4YNVe8aqsJV3vJcyHo3Xhu2ZtjPvglLwldeR0EIe5ezQhg7p6oklB0KWyOcpdrKQtrhs1wb1vIK5sKGyWiysoKsEPcuYlGYO6sjL9QlapaFu5ymopD3rmqVsHdGV1bgNZK0KPji1OSHwINJYHEYzCniQ+G7irpwmLOcGxLfNSwNizk1paHxXdVa4TGnriBEvgurCJOJhkSofDxw9o+HtQPlrsfSOPl4WBQm91YXRMmcgoIgefD7l8bInKLcELmXszRC5rTwAXKvoC4+5uzOhse96eroeNZ67uVfFBtzKkpC417MGpExr6koML7LWiUuHisrDIvvT291VMzZnw0kyOixrv28kLiXsCwinlGRGRCPtCyMh9OKysLhXtM60TCrKi/kGghaFnGltRSEwrfhfnkknNYzEwj3Girj4LTd7DC4V7A4Ck5rKQ6Ce02rxcBpbSUhcC+rJgIeKUgGwO+/lbyA99/K9cPgvtPySPiqd1kwfLO9KB5mdRSFxMNrsTwqZnXlB8Y3UctjY1bRXHh801EbIbPWM4Lkm4AFcfK8hoIbsjBaZrWUBcw3SevEzDPKCsPmgbiVImeirzh4HjznC+JnVkVGAEJHm9VV5AbSNyFLY+k5Ldnh9FjR4oia0VUaVN+UrRVX89pyw7ihrKWRHKOoKMC+TxhrxNiMqtkw+6akOtJmrBcE2zcdK8TbjKKKkPumbMWom1FYFnjfxNXF3mMdJPx+2R7PXx8e0Xfdb8fWCrpH/eXG2zeBg5+wkffpuNk/Hn9/vYaqP//SwLs8NjtpX2159+u8tbZNtYVfmt9/xmHp2MqtXbWl75rT5RmOZ2NLx75diaX81GhsrCIrmreekRBN/LQ2F5pXM5cGjaXUZkDzOnK8rCzvmbeZTHnGZouznUzLeZe8KseZV5CT3oyFLMlscvRkJTVU0qJ8BqnKTGXoE1qcxczbTgZ4cHRY0/ZT085Q87bvDYtG4/wUiZiryo6yFMwkRkBHZU40p6aLDrLDiCXXvuuieXqf6+i3M5DHF1rPS/zG9pflfBmK+ERiIqYuh8jQ8beM0O5Tcy6O7kgy+REu+iCzbmy1wMpsykoNVmerc1qecxKNt12r6l+cSIepkaJMeM5m92mrrEyq/w7W0t85m3iPrVbn3Bk6/iMn8zo15/KMiyT2eR50a7fQ0t8PP+6ft+fHz7km94fL7YQFtjPLF1TBwspFxrh4PXxNm/C+jsn4eL0kp7559fXIKZaMTZfUSeas/7p93j1tz813zen1sD9lPGj9Gcf7GUV5OS7QJFYIDg6vXaYpXSM4VLq4WHMzXl6vYezzJZv7ooiseZ2xM1+4udnKr90w9ubLNzd7+RWc2sWeE5ML6jhLl3siX15azVm04HMiaGlNp2LJ59Tfq3LnukWfE+PV9Z36ZZ9Ywx9yB0oKPaus/MxUVVTuWWvtZ0JbYdFnyerPLAWzidKS9Z8ZCjIKQPcll/k1oOolp1OjiypBCxedYjUL60GMpoySEA1WFt6NksIQNV1UG1q82HaiYp0K0ZLltkjSsryXV8OXioYqaqLKooLRYFFvXs1o2VJiYHZx5YhdTMyn/oPlxHm5f/nCZWCqqorEWB4UkjIzvmE56fW49L5nF5WWr53OUzNTWhrKqMoPCwtMg+XZK/hZQZmJGC6qNK2xPB3oWKnexI+veSWn4ThbVnVauDx+IqCm9sRoKCk/3TTUVKDYRfrn4+4VWb7+fa2y062v3HpTK6qmQHG3VFGZ4K1mlCRGv7O2FsGrmCtC3CXUVh94+7jscLdaVm/gbSULDXdzxRWGDIvzl7aqpsBbzikm3AUsqSLM6cgqHwylLKobUDWZBYPhk1ZcKeBtJoPiydO9lk0+Rb+brcvNZy3PJOXEfmU2zqnIS0jvOpZlojNK+BB5JKIuNubsZ6Rmg6G2PifjNCQSpLvdwsyIs9XlN22br3efPs/84q756fqX5655dgwxtHtstk8Zs/i12XT+LrBzas5fHa9C97Pxyqk5Pwyb1trL9d/q3G7G/nf/+tWs4eOnhwW/MOPGnZrzovuW/lrPwMj8R3rmbaBv81AT3Cd5WAvZCeDd4OLMj9OTk3TdpZRkW9SqsYNk4WamHTA/bh+b079sn9jcZkRgabox7QYmG0OJ26cktubk0Wg6r8vj6bTjOu2Ol3Z7AjcO9J5zx0ZGhjfrT0+/Nsfz7tS8NPtzytKkUf6tfNnuLx+3j+fLsTmWdf92eCr746a/oe6CJnTkXF9OwvByPxyefkemr3/Pv6hxGvl6dzqzfb2N7Z5jOyy8FZR6UvYfj9tj8xQ/kjBvrm9/bNuXmKWX6P3n7f5Tk7IWj+ZfLprVpLuDuQ3V3Ynjjf3w+2uO/t7gOTavNfq6PW5fmvMgc2RMDhsXGBzeo2vyAIfn9kCpI/Mdvb01wmKjloSB/XgGxgbAnJtt4LfrlDzTf98mr/vRdT48H45tmD6YxL/anrDFVOP8+/HwfKno+m13WuL3JX9DSsQ0fi+QMh/RFwt6vJ7w87UEVSFodPKqgs7NS5udXY71usZ9rCTv6fotxgpJ/Xkryfh0bJp9hYz+vJVkPB8Orz/v9k/N/1ZoGZ28kqBxkTdfS1nlt07WX1GxvVBiVRm+Tu4SmX+svNfDbzgamJHWn7eSr70em1MDw8Y5Hf2JKwk5NjD+m1ERz1pJwum1qRLRn7eWjFExp0AGW97JkTGMbJ6a5+bc/Gfz8Plw+GXCYweqYMOCiCaRcKW7fdudgn8n1p0aI5rTaYvzGMb+/awVJER2/z4RuzAq4omPXNwyJ2R8v1ORfjxSmjP8DT5Jg766tIGp53SSWDOpAX5qaDKcl5pKZYxTU2yyyJtq9tuH5+b98+Hy1D2ncybjGY/XM063M2pMf748/Dnz1n2+PCy8e1dmtjvA6G9o6N4s08jUpVNlkfvRNdJh0ttcTjyQxmmHCVZ3aI0h9t7R3KAa1dQMowMb8wMna2ZuqBxYyhocqbHp9SdLsSbW4vE1h8ZBj7kDZCdywTA5NVoU++bL4IfQqYyMgZQ3WzKcDs3PDKpLr0bWUDvUkz/g8oZnh92h0bzBd2Iw9Rh91/zPpeHG4lGztYa3aac5Q91Yce2wB2znDYFZ5nOGQ6Age2hMiZje3y7CTMvoGpQQgf25+V/GV4Y9vr235n5PrzI1VPza7M/8ADUy2rbPGKByzP5j7rGcWs57OKfGk3fvfeYl79qVTnrfbB+Luu5mgJf2tIyf2MtfMP+kVeTf5hkZ591L8+3H77cvr8+FQq5nHj6e+jOrpAzv/V+Ox8Px24f/Hq6pGggZHC55avFYRDt7y44+Q2XlI+/E1tyIi80NL1UeZp22WiOvSPQ6l18AyYnfdmRsH9dM/Ue9zce2N2FVcS0yxhYA5szNRGxjeznR2pzByOhTA9bYXmzLDlLA3NANrnsirsVAtBRpYBY0K1g0dDkffr5uV/n5dXs54UprysBbcDL+oeiXpALH7fncHGHsmNRxP2ex+cft8+7huD0nJv6khPF5i2U8HQ7Hnw+vmMQlRQzPWkHC5eG5ibc3RXEZJZOTFwtKErikijL2Vipljrrxsqp4W6nEOml/lKT9FXT8PN5mmCNqfN5iPzol60dJBTN7+QqMX/aPz4dT8/Tz9nl7fCkSMTl1BTHXB7RSDDl1uZjX637Bn6/LeX8+NY+H/dP2+PvPo82wWcK4bmpEDmfkvx8entvpH7rP/Wj+/Lu/npPR2du+If4JA2Epptwcd6+fm+MWDqHU2qh1gcnhxfpwXTEHL1Q8UhDBXtIz8qCvt4N2WHMnqWiN89AAEzryXSfnrmHv0+kq30DSj4YGeB/iDfzPZYefxKGBvlGmgZG3PF8+fbPb7zKW7CWaFqTEl+NV0ofUag/OwNvuZH7JR+rXlK79YpXwK78KJaQ9lJNQFmHVSJqLsublVUVaNVLrJf6R0q47IZ8PeHsJq2xw4ioellxCw6rgF9CUSvh9//jj+fGHXcWNup57OT+ed0zBolDOta/yAag/axUJv+0+7r5LbMRhVVxPZHfozAsZDv+vl9NnhkUNDq+yg4H2N7uFYaivbg9DyiRbIcowy+5imBid38aATU7vVXrx2fD4cmI46Y1HhSNx5ZXqqbW5UnWOQZ4KTm1m4MCE2dR9+irj6n5VtJ2qc19ceoXd9h7PRNETyfiX/c+lOf6esQwStVvukcleec+Eoss9NG19zlNLBPAem9aQ4bkzMob3+bsLTmquf8+/j83+Aosbt17edi2w3lZEcqMm3J9w7zk2qOr4q9/PuM4w6v2ha1VhYgcT6kHvu3QmPdNxjvbdvl77a1vxn9F/b1Ru4Nj8z2WXWP5+tzBoVW7inAgU7t2zoQHpevjYzACjKlCUzA8zqu5D2fNFtlNzvrxmDO6o3fLBPdkrP7hD0eWDe9r63OBeIoAf3NMaMgb3GRkjL/1td378/NXh/NXXf/lzkndPW+Xf4z/tjh8ux93HHQ6OE12/3e6Or/fTEm48FT8v4odtokiXoeS85Wp3+XK+et7tn37YPcM0K6Xj4XrSece8tL9AwKHM9GENo++b3fNu/2n87p4M64/xPP4lPnUyhu9WLVTCvWO1QMx189FXl+eHIhnXkx7iScsF7M/bx3P8TmyZiPbEU3/iYiGX43mLo6GkhNspKxlXFdbVCub/7fIgS0x/ju1XMFv0iz/H9svNvuyeiieEz8Ozlkr4OkE0U8ZZdFlmtnDImXudc77xb1L1qZRpvkRVaPjDM8b9rPHXZwb4lwoou+7R/noXvvsAd4WCx8Maz/o3h/ZttMXD/Et73mqj/LeX83WBVLEvHuJ5a7lkXxf/9w8lIl6fL59edvvdf7+uKOHH72skrPJcfLjuVN8/NuVe8dqduZpfgLc6ZsjIeLljvoQf97/sD78VBSCX2ykVxmEa9v3jdr+feTS6NgVLN7p3sWb3+nZwxswv6wWn0NZ2x9/RkdmudbHJ4aX84f5emIxlDOnWBVWM9GrZme5nF80yPyZFBJrn0w5PtXNi7qeuJebj9vOx2X9usA/M6Rmdvb6k5ILafF38stpycTHGPVe50uDcteQky41zWspWpFQKm1uUkiWyal1KpeBFQtcXOBw044LNjHovbLi84Jvulq/4Yt3lJV/G/lzNt0gCX/RlVGRUfeeEDO931+rPzXm7g0/4qEEBjz4223OTWtoz7fRtPIFdzzPWym56Su1AA4YzXjCaZTjuh880emu8wODz9nT+sb3VBZf5elL0j+WX+movz2psWWZq6KW/9b6cXJI0blGw4+oxtZQZ9Pj21hr/FCKzykOR2QwXzTOduGPIJnfLksbkJjhh7l/42QLkc8Wop38ZHGFvFtPjh2+kSWzMntiYtq21imjuxFwu0+XsjPfFTE3Mv1eF6X3Mviadt4cX9V1ycxInLLKfdZtoy2UWZ27YoNEiO//49v2MkX98+36phawfc2u31FqRo0zaL7JeZHodu+wNXHDvMm7b4jtWcLNWu0+5BhdY66ov73fHx8vz9nw4/nW7J4ZQk8U20qPUTOvllpGnpBsutsfexPkTiuzfaqzpy4ualP3GycKN7qf0f6/rjXEI0KTSBrz146N1PfM3Gbcqs3SY9Hoo7oG5xof6q3tIXNdD1RU9zFxLeryo90e0/CZ2PDxU3ecQsE677T9KWtlz+u6lGy6yh+4qbLPECnu32bbVVvMu5BpXcfYSLrx+2RdvyZWbnTxBi3oL/E9aaZ58nCw56/rv/17XG+NYoEmlDXgHxkfreuavPG5VaGm6Ma3v/XaksEe0cq/vc3CsvlfunuJmC2zheztpUW9h5h4nW5ZZJMsYu97jX2t6UrgrVdUXc0OnLaos8BcZNqqxM/tDFv4O7I3DYzW95lycBdfm4/PhcHz/3Gz3u/2n7w7XIFRsiBXYZrkVeL2Ylsststcy44wiBZ+HC3SjieufivtIuy05Wt4zugH3A8X9sZd32qC0f2YkIkcLe54sLe477Q9U9sfeOtSo2g6+keR4be8ztzXRrtJaziVbfsVmLtii65V5uRZcrb/tr+ta329fSOe3vxf1tuvPao5bVnu6YZG9X5rfXwdvNYl9xz9W9PPn5tw8nrmwM9muwtoPh8vgHXjD/tsjtT2ylz3ZrsJahqEFNkbvfIt9Xv9U3Me0KtT9taantGNMG1T1j4aS0bGaXtkbBdsUW+EvzJKrkrwklddj9mIsuBLfbB//RL6/Hfu9Hyjqb/xGl9hV+7fyXkbbXwY9Xf9e11v6lqMmlTbQzSdH63pm3SDRqsLSZPDp/1zV1/tvmSgQN6q2k77yg+O1vWdcfdCuytr8BVt6tdhLteA6ZV2kpVdo5vIsujbpC1N7VeYvyZLrgXaodV0PDlX3yVxq3KreErzwkwbV/fO3IdmwyN5hv336tTmed6fm5br8b2yEHC3sebIfqe+0P1DWH9pS2PU4OFTdZ9pvEq3qLSG/mTao7p/1m3TDInuv2/31HRXThPZ+oLI/SfOR4aHSPn+IJ7JXJNWszNbz5RPt9/nyqbiP61ZR0M/1z1V9/fuHtF/DNpVW+CucaFZlCz4944NV/f74/fyVGrWptJJ1pWizYlvJq1R5hWZVL9GL9yd3fY8OLuiXubupdkuswesPmiywwd8TpmmRzeP1zddxU67ApkCLagsfvpm3cWuzwEraG5LtllhD3oCaVNvI+z1r/JrZ31L1S67fb5r0ef1jRT/ctSDHy3q/AsZ/bB8vl5eWOTbH7wU1AJostgGKSqlmq9jCd5htvIpddjzLO2mxjuzfvtLvLv7N6/7e9JPCtS2yepq+8iOauB+o7C+tHraptYI8gh6u7Ju9+6lmRbZ+256b49fN9pcephEjk+PLek/fEq7pQpvoBiVaLbPE3q6Z1qxlNUxau5fGv//cPP4yKHX8uj3urtuUrgnruElu15fj8wl0d/0zf12sFHr4HpRT8+N3X3M9vb22uTB7TNuWP/98vXJpQ0/Nc3OefFsZmYstf7u1XGT06pWnuR/YNVv8G4cv6GYNtg1X+YXD18ayJtuGq5gcvbOAtRlb1hm11OBXxFM/XvbtFu/+FQzdceT8//Xuusii+d83X/7z9s34L9/IL9QX4c27Nx93zfPT6c2XP0V779plv7F8+nR4vLT//K+u2T/aweDaOLb+l82bdz9t3ln3hTH6v/7r3U/9ye2B9g99H/e/tCeKN+9+EuhEMTlRjE6Ub979JNGJcnKiHJ2o3rz7SaET1eRENTpRv3n3k0Yn6smJenSiefPuJ/POyi+0tqMTzeREMzrRvnn3k31nwhcbL0Yn2smJdnSie/PuJ4ekusmJbnSif/PuJ49O9JMT/ejE8ObdTwGdGCYnhrEDXP1BbN4Z+YUPYw+Y+o4gztN6j0DnAvcZ+4+4eoWQ6NypB4mxC4mrYwiFzp06kRh7kbj6htDo3KkfibEjiat7CIPOnbqSGPuSuHqIsOjcqTeJsTuJq5MIh86dOpQYe5S4+onw6NypT4mxU4mrq4iAzp26lRj7lby6ikR+Jad+Jcd+Ja+uIsU7o78wdvzkyaljSTIwtSMTciwJhqaxY8mrr0j1ztgvjPXjk6eeJceeJa/OIjVUPXUtOXYtefUWadBgI6e+Jce+Ja/uIu07s/lCbojsqXPJsXPJq79I5Fxy6lxy7Fzy6i8SOZecOpccO5e8+osM8HJNvUuOvUtdHUYh71JT71Jj71JXf1HQu9TUu9TYu9TVYRTyLjX1LkVmvnbqQ8OWAnPf2LnU1V2URv6hps6lxs6lru6ioHOpqXOpsXOpq7soNHCpqW+psW+pq7soh54nNXUuNXYudfUX5eHJU+9SY+9SV39R0LvU1LvU2Lv01WE08i499S499i599RcNvUtPvUuPvUtfHUbDsEpP3UuP3Uur1Eyup+6lSWzVBlcwLNMgvBq7lzapMEBPvUuPvUtfHUbjsG7qXnrsXvrqMBqGdnrqXnrsXvrqMNrCk6fupcfupa8Oox16ovTUvfTYvcwmFfqYqXuZsXsZkQp9zNS7zNi7jEyFPmbqXGbsXEalQh8zdS4zdi7TOpeHEfjUuQwJ3k0qbjIgfB87l7GpuMlMfcuMfcu4VNxkpq5lxq5lfCpuMlPPMmPPMiEVN5mpY5mxY9lNMm6yU8+yY8+yIhU32aln2bFnWZmMm+zUtezYtaxKxk126lt27FtWJ+MmO/UtO/Yta5Jxk506lyXJoU3FTRakh2Pnsi4VN9mpc9mxc1mfjJvs1Lvs2LtsSMVNdupdduxdbpOMm9zUu9zYu5xIxU1u6l1u7F1OpuImN3UuN3Yud3UXHZB/uKlzubFzOZ0KfdzUt9zYt5xJhj5u6ltu7FvOJkMfN3UuR4oPLhn6OFB/GHuX86nQx02dy42dy4Vk6OOm3uXG3uWv/mJgDctPvcuPvcuLVOjjp97lx97lZSp68VPv8mPv8io1k/upc/mxc3mdmsn91Ln82Lm8Sc3kfupbfuxb3qZmcj91LT92Le9Sk7GfepYnpS2fmow9KG6NPcuH1GTsp47lx44VNqnJOEz9Koz9KojUZBymfhXGfhVkcjIOU8cKY8cKKjUZh6ljhbFjBZ2cjMPUs8LYs4JJTsZh6lph7FrBJifjMPWtMPat4JKTcZg6Vxg7V/CpyThMnSuQ0mlITcYBFE9p9XSTnI3jsfHpg79154vUhBwP0dNJEXUjk3NyPEbPJ4XUjUpNy/EQPZ3UUjc6NTPHQ/R0Uk7dmOTkHI/R80lJdZMsTcRD9HRSVd2kqxPxGD2fVFY36QJFPEbPJ9XVTbpGEY/R84nviWSZQqDa/aR4n65UCFi/J77XFuUNhkeohk+L+CJZrxCojE/r+LGQj+ED8D1aym/L8ziDF6iaT8v5sZ4PnxxU0KcV/VjSh08OqunTon6s6kOKgcr6tK4fC/sQZKDKPinti7ZcjxN6Aar7gpT3RVuxxywE1PcFKfCLtmiPcQgo8QtS4xdt2R4TEVDkF6TKL9rCPYYioMwvSJ1fxEI/9HpQ6Bek0i9iqR8/tKDWL0ixX7QFfAMrjALU+wUp+Iu2iG9goVCAmr8gRX8Rq/4Y+wHPI2V/0ZbycWwjQOVfkNK/aKv5RkPPBcV/Qar/oq3oGwN/PgAAghAA0Vb1jcXnI3ZJnE+lGZMAHEAQECDa2r5x+PcD9yMsQKg0aRIABwjCA4RKwiYBgIAgRECoJG8SAAkIwgREW+Y3kK8LQAUEwQKiLfUbiNkFIAOCoAGh08EeYAOCwAGhmWAP4AFB+IDQ6WAPEAJBEIHQ6WAPMAJBIIFoC/92A10PcAJBQIFoa/9W4POB6xFWINryv5X4fOB7BBeIlgBgAicAMBCEGIgWAmAIJwAzEAQaiBYE4GAXYANBuIFoWUAi2AXoQBB2IFoekAh2AT4QhB+Ilgkkgl2AEARhCKLFAlbB2wcogiAYQbRowELQJABJEAQliBYPWMiaBKAJguAE0SICHKwDoCAIURAtJbB44gBQQRCqIEy6NicAWBCELIgWFli4pkkAtiAIXBAtMLB46AV8QRDAIFpmYPHQCxCDIIxBtNjAwfKiAJRBEMwgWnLgxDtlvxCBrt8B7kdIg2jhgcNxF2ANgsAG0QIEp94p94WzhpyPFhAR92shgsPuD5iDINBBtBwh9fuB/xHuIFqW4HDgBNCDIOxBtDjBYf8H9EEQ/CBapOCw/wICIQiCEC1WcNh/AYUQBEOIliy4AIcPACIEIRGipQt49AEsQhAYIVq+4LH7AxwhCI8QLWLwONcHREIQJCFayuCx+wMoIQiVEC1p8DjtAGBCEDIhWtjgsfsDNiEInBAtb/DYfQGeEIRPiJY5eOy+AFEIwihEyx08dl+AKQThFKJlDx67L0AVgrAK4ZnhD+AKQXiFaBmEx5U+gCwEYRai5RAB+y/AFoJwC9GyiICDR4AuBGEXouURAQePAF8Iwi9EyyQCjl4AwhCEYYiWSwR9Hf61ItcPYAxBOIZo2UTA/gtQhiAsQ7R4ImD/BTRDEJwhWkQRsP8CoiEI0hAtpQi44gSghiBUQ7SgIuDwAXANQcCGaFlFwv8B2hCEbYgWV4jNBt9A4ICEb4iWWYiNgAEAYByCQA7RgguxkbgDtJyXrueNC8XbEERs6JJetKaXLOrdREir3ynzRRCKdADW9RLYIVt4ITbmehd0oB2Axb2EdshNrDhbdA0k4B2S8A7ZAgyxcbgDsMiXEA/ZEgyx8fgigoW+BHnIlmGITcAKwGJfAj1kCzGE2OAOwIpfQj1kSzGEgJ4oAfaQBHvIFmMIAT1RAu4hCfeQccuCgMGwBORDEvIhu30LGneAVpgTT2xRBh6OJUAfkqAPGdGHMFgAcEQCP2QHP7AnA/whCf6QcSuDgCOyBPxDEv4hRXpElACASAJAZAQgAoYkEiAQSRCIjAhEwDFdAggiCQSREYJIWJGSAINIusNBxnWcMCqWaJcD3eYQOYjE26jQTofJVoe4iQbGFRJudyCOGFmIhIGxRFse6J4HmQ4MJdr1QLc9tHxDSBiZSLTzgW59kJHDwdBEot0PdPtDSziExE8C2gJB90C0iENI7MloHwTdCCGjI2JPRnshCBWRLeUQCobHEmARSbCIVHFVMfZkwEUk4SKy5RxCYU8GYEQSMCJb0JHwIwBGJAEjUul0gCUBGZGEjEhl0gGWBGhEEjQilU0HWBKwEUnYiFSOCbAAHZGEjkjlmQAL8BFJ+IhUgQmwACCRBJBIvWECLEBIJCEkUgsmwAKMRBJGIrVkAiwASSSBJLLbRYEDLIBJJMEkUmsmwAKgRBJQIrvtFNgTASmRhJTIlnykAiyASiRBJVI7JsACrEQSViK1ZwIsAEskgSWyhR+JAAvAEklgiYxbLBQsGEmASyTBJTLus0hEaICXSMJLZNxsoSBqlgCYSAJMZNxxoWDNTwJiIgkxkSYuMLXvtP1CGbqnEDgiQSYybr1QDneAdiUSR4z7LxJRKoAmkkAT2VIQXPWWgJpIQk1k3Iih8NQMsIkk2ES2GCQxLQFsIgk2kXbDTEuAm0jCTaQVzLQEwIkk4ERayUxLgJxIQk6kVcy0BNCJJOhEWs1MS4CdSMJOpDXMtATgiSTwRFrLTEuAnkhCT6R1zLQE8Ikk+ERaz0xLgJ9Iwk+kDcy0BACKJABFug0zLQGCIglBkU4w0xJAKJIgFOkkMy0BhiIJQ5FOMdMSgCiSQBTpNDMtAYwiCUaRLRZJTEsAo0iCUWSLRYTCkT7gKJJwFOkcMy0BkCIJSJHOM9MSICmSkBTZkpHUtARQiiQoRfoNMy0BliIJS5Fxs0diWgIwRRKYIrsdH3g4ADRFEpoiWzqSmJYATZGEpsi49UPjfA3gFElwimzxSGJaAjhFEpwi4x6QxLQEeIokPEXGjSCJaQkAFUmAioy7QRLTEiAqkhAVGbeEJKYlgFQkQSoy7gtJTEuAqUjCVGQQzLQEoIokUEUGyUxLgKpIQlVkUMy0BLCKJFhFhuiIkItJwFUk4SoyxI1IOO8HYEUSsCJbUCLwznMJyIokZEV2ZAXPrICsSEJWZEdW8MwKyIokZEVGspKYWQFZkYSsqEhW8MyqAFlRhKyoSFbwLnoFyIoiZEVtmKlZAbKiCFlRG2ZqVoCsKEJWVCQrGtYBFSAripAVFckKntsVICuKkBXVghI8tysAVhQBKyqCFfxCAQXAiiJgRUWwouHiXAXAiiJgRUWwgtflKwBWFAErqgMrMLpQAKwoAlZUB1bgiKYAWFEErKgWlOCZVQGwoghYURGsaBhgKQBWFAErSqTr2QpwFUW4iopcBc+sCnAVRbiKivtK8MyqAFhRBKyoCFbwzKoAWFEErKgIVvDMqgBYUQSsqAhW8MyqAFhRBKyoCFbwzKoAWFEErKgIVvDMqgBYUQSsqAhW8MyqAFhRBKyoCFbwtKQAWFEErKi4zQRPSwqQFUXIiopkBU9LCpAVRciKimQlMS0BsqIIWVGRrCRmFUBWFCErKpKVxKwCyIoiZEVFspKYFABZUfQ1Uyq97kahN03RV01FsGI28D1E6G1T9HVTEawYAd/dhF45NXnnVHxxC1y6pOB7p4gjRrKSmBTQu6foy6ciWTEK/wTgiPQFVJGs4IxRoZdQ0bdQRbKCM0aFXkRF30QVyUpiXkMvo6Jvo2pBSWJeQ++jImBFRbBicIQHwIoiYEW1nCQxrwGuoghXUR1XwfMa4CqKcBXVcRU8mgCuoghXUZGrJOY1wFUU4SoqcpXEvAa4iiJcRUWukpjXAFdRhKuoyFUS8xrgKopwFRW5SmJeA1xFEa6idGDmNQBWFAErKoKVxLwGwIoiYEVFsJKY1wBYUQSsqAhWEvMaACuKgBUVwUpiXgNgRRGwoiJYScxrAKwoAlZUBCuJeQ2AFUXAiurACp7XAFhRBKyoFpQk5jUAVhQBKyqCFbwRUgGwoghYUSYwEyMgK4qQFRXJSmJiBGRFEbKiIllJTIyArChCVlQkK4mJEZAVRciKimQlMTECsqIIWVGRrBiccgKyoghZUZGsJGZWQFYUISsqkpXEzArIiiJkRUWykphZAVlRhKyouDEFP0oArCgCVlQEKwYu/1EArCgCVlQEK3hXqQJgRRGwohwzNQOuoghXUY6bmgFXUYSrKMdNzYCrKMJVlOOmZsBVFOEqynFTMwArioAV5bipGYAVRcCKctzUDMCKImBFOW5qBmBFEbCiHDc1A7CiCFhRnpuaAVhRBKwoz03NAKwoAlaU56ZmAFYUASvKc1MzICuKkBXluakZkBVFyIry3NQM0IoiaEV5bmoGaEURtKI8MzUDsqIIWVGRrCSmJUBWFCErKpKVxJAMyIoiZEW1oCQxJAOwoghYURGs4H32CoAVRcCKajlJYkQFXEURrqI6roJHVMBVFOEqKnKVxIgKuIoiXEVFrpIYUQFXUYSrqMhVEiMq4CqKcBXVcRU8ogKuoghXUR1XwSMq4CqKcBXV7VjBfgi4iiJcRXc7VuCIqgFX0YSr6I6rQDymAVfRhKvoDbMaUQOuoglX0RtmNaIGXEUTrqI3zGpEDbiKJlxFb5jViBpwFU24it4wqxE1ACuagBW9YVYjagBWNAEresOsRtQArGgCVvQmvRpRA66iCVfRkask3jUNuIomXEVHrmLhggENuIomXEXHr21gtqQBWNEErOgOrEC2pAFY0QSsaMGUETUgK5qQFd3tWIHDgQZkRROyokV6C70GYEUTsKIjWLFwkbwGYEUTsKJFeg+9BlxFE66iO64CpyUNuIomXEV3XAU/y4CraMJVdMdV8LMMuIomXEV3XAVOSxpwFU24iu64CpyWNOAqmnAV3XEVOC1pwFU04So6chU8LWnAVTThKjpylcS0BLiKJlxFS2bJgwZcRROuoiWz5EEDrqIJV9GSWfKgAVfRhKtoxSx50ACsaAJWdAQrFn8qAYAVTcCKVsySBw3AiiZgRStmyYMGYEUTsKIVsxpRA7CiCVjRKr0aUQOuoglX0ZGrWPzVB8BVNOEqWjGrETXgKppwFR25Cq4/acBVNOEqOu5YwfUnDcCKpl/6iGAlMaugr33Qz33EHSv4xUIaffGDfvJDp5c8aPTRD/rVjwhWLCzFavTlj8mnP9JLHjT8+AdxQ80sedDoCyD0EyCaWfKg0VdA6GdANLPkQaMvgdBPgWhmyYNGXwOhnwPRzJIHjb4IQriKNsySBw24iiZcRRtmyYMGXEUTrqINs+RBA66iCVfRhlnyoAFX0YSraMMsedCAq2jCVbRhljxowFU04SraMEseNOAqmnAVbZglDxqAFU3AijbMkgcNwIomYEUbZsmDBmBFE7CibXrJgwZcRROuoi2zc0oDrqIJV9GWWZ6tAVfRhKtom16erQFW0QSr6IhV8MvWNMAqmmAVbdPLszWgKppQFW2Z5dkaUBVNqIq2zPJsDaiKJlRFW2Z5tgZYRROsoi2zPFsDrKIJVtGOWZ6tAVbRBKtoxyzP1oCraMJVtGOWZ2vAVTThKtoxy7M14CqacBXdcRU8ogKuoglX0R1XwSMq4CqacBUduUpiRAVcRROuorsNK9gTAVfRhKvoyFUSIyrgKppwFR25SmJEBVxFE66iI1dJjKiAq2jCVXSLSRIjKsAqmmAV7RnQrAFW0QSr6A6rYE8GWEUTrKLj67/wJQRURROqoiNVwa+P1ICqaEJVtE+/bUQDqKIJVNGeef+SBlRFE6qiPfP+JQ2oiiZURXvm/UsaUBVNqIoOzPuXNMAqmmAVHZj3L2mAVTTBKjow71/SgKtowlV0YN6/pAFX0YSr6MC8f0kDrqIJV9GBef+SBlxFE66iA/P+JQ24iiZcRUeuYnEhFXAVTbiKjlwlMSQDrqIJV9HdfhXsyoCraMJVTLdfBbqyAVzFEK5iIlfBQ7IBXMUQrmIiV7HwdZoGcBVDuIrp9qvAMd0ArmIIVzEtJsFjugFYxRCsYiJWcfDlQwZgFUOwiolYxUE2ZQBWMQSrmA1TvDEAqxiCVUzEKg4uoDIAqxiCVUzcr4KrPwZwFUO4iolcBVd/DOAqhnAVw+1XMYCrGMJVDLNfxQCsYghWMRGrOFiCMwCrGIJVDLNfxQCqYghVMdx+FQOoiiFUxXD7VQzAKoZgFcPtVzEAqxiCVQy3X8UArmIIVzHcfhUDuIohXMVw+1UM4CqGcBXD7VcxgKsYwlUMt1/FAK5iCFcx3H4VA7iKIVzFcPtVDOAqhnAVE7kKnhgN4CqGcBUjmVzFAK5iCFcxkslVDOAqhnAVI5lcxQCuYghXMZLJVQzgKoZwFRO5SmJiBFzFEK5iFPNqRAO4iiFcxaj0qxENwCqGYBUTsUpiYgRYxRCsYiJWSUyMAKsYglVM3K+SmBgBVzGEq5jIVRITI+AqhnAV0+1XwRMj4CqGcBXTcRU8MQKuYghXMYpZA2YAVzGEqxidXgNmAFYxBKuYiFXwC+sNwCqGYBWj02vADMAqhmAVo5k1YAZgFUOwitHMGjADuIohXMVoZg2YAVzFEK5iNLMGzACuYghXMZpZA2YAVzGEqxjNrAEzgKsYwlWMZtaAGcBVDP3UumHWgBn0uXX6vfWOq+CJEX1znX50veMqeGJEH16nX17v9qvgeQ19fZ1+fr3br4I9EX2BffIJdsPMa/Az7MQTO66ChwP0LXb6MfaOq+BpCX2QnX6RvcUkiWkJfZSdfpW9wyp4UkBfZidYxVgGNBvAVQzhKqbFJIkRFWAVQ7CKiVgFf4LDAKxiCFYxNv2KTgOwiiFYxVjmFZ0GYBVDsIqxzCs6DeAqhnAVY5lXdBrAVQzhKsYyr+g0gKsYwlWMZV7RaQBXMYSrGMu8otMArmIIVzGOeUWnAVzFEK5iHPOKTgO4iiFcxThmUawBXMUQrmIcsyjWAK5iCFcxjlkUawBXMYSrGMcsijWAqxjCVYxjFsUawFUM4SrGMYtiDeAqhnAV45hFsQZwFUO4inHpRbEGYBVDsIrxzMtGDMAqhmAV47niDeAqhnAV45niDcAqhmAVE7EK/iiRAVjFEKximK+qGIBVDMEqxnPFG4BVDMEqxnPFG8BVDOEqxnPFG8BVDOEqxnPFG8BVDOEqxnPFG8BVDOEqJnDFG8BVDOEqJnDFG8BVDOEqJnDFG8BVDOEqJnDFG8BVDOEqJnDFG8BVDOEqJjArbwzgKoZwFROYlTcGcBVDuIoJzMobA7iKIVzFBGbljQFcxRCuYgKz8sYArmIIV7Gb9MobC7CKJVjFbpiVNxZgFUuwit0wK28swCqWYBW7Sa+8sYCqWEJVbNytgj/TZgFWsQSr2E165Y0FVMUSqmI3zMobC6iKJVTFbpiVNxZQFUuoit0wK28soCqWUBW7YVbeWEBVLKEqVjArbyygKpZQFSuYlTcWUBVLqIoVzMobC7CKJVjFCmbljQVYxRKsYgWz8sYCrmIJV7GCWXljAVexhKtYwVSzLeAqlnAVK5hqtgVcxRKuYgVTzbaAq1jCVaxgqtkWcBVLuIqVzMobC7iKJVzFyvTKGwuwiiVYxXZfmodMwgKsYglWsRGr4NdcWIBVLMEqVjLbpizAKpZgFRuxCv7ypAVYxRKsYiXz9iULsIolWMVK5u1LFmAVS7CKlczblyzAKpZgFSvTb1+ygKpYQlVspCr485kWUBVLqIpV6Vc8WABVLIEqVjGveLCAqlhCVaxiXvFgAVWxhKpYxbziwQKqYglVsYp5xYMFVMUSqmIV84oHC6iKJVTFKuYVDxZQFUuoilXMKx4soCqWUBWrmFc8WEBVLKEqVjOveLAAq1iCVaxmXvFgAVaxBKtYzbziwQKuYglXsZp5xYMFXMUSrmI184oHC7iKJVzFauYVDxZwFUu4itXMKx4s4CqWcBWr0694sACrWIJVbMQqiWkJYBVLsIrVzNuXLMAqlmAVa5jijQVYxRKsYiNWSUxLAKtYglVs930VPC0BrGIJVrHd91XwtASwiiVYxXZYBQ8HAKtYglVsS0kS0xKgKpZQFRupCv4qswVUxRKqYuPnVfC0BKCKJVDFxs0qiWkJUBVLqIqNVCUxLQGqYglVsd33VfBgAKiKJVTFdt9XwdMSwCqWYBXbfV8FT0sAq1iCVWz3fRU8LQGuYglXsR1XwX4IuIolXMV2XAVPS4CrWMJVbMdV8LQEuIolXMV2XAVPS4CrWMJVrGUWxVrAVSzhKtYyi2It4CqWcBXrmEWxFnAVS7iKdcyiWAu4iiVcxXbfV8HTEuAqlnAV22KSxLQEsIolWMU6LlcBWMUSrGId84oHC7CKJVjFRqyCvzNvAVaxBKtYl/7glAVUxRKqYiNV8XA9pwVUxRKqYl36g1MWUBVLqIr1zAenLKAqllAV65kPTllAVSyhKtYzH5yyAKtYglWsZz44ZQFWsQSrWM98cMoCrmIJV7Ge+eCUBVzFEq5iPfPBKQu4iiVcxXrmg1MWcBVLuIr1zAenLOAqlnAV65kPTlnAVSzhKjYwH5yygKtYwlVsYD44ZQFXsYSr2MC84sECrmIJV7GBecWDBVzFEq5iA/OKBwu4iiVcxYb0Kx4swCqWYBXbYRU8JAOsYglWsYFZimgBVrEEq9jALEW0AKtYglVsYJYiWoBVLMEqbpNeiugAVnEEq7iIVTxciugAVnEEq7hNeimiA1TFEariNsxSRAewiiNYxW2YpYgOYBVHsIrbMEsRHeAqjnAVt2GWIjrAVRzhKm7DLEV0gKs4wlXchlmK6ABXcYSruA2zFNEBruIIV3GCWYroAFdxhKs4wSxFdICrOMJVnGCWIjrAVRzhKk4wSxEd4CqOcBUnmKWIDnAVR7iKE8xSRAe4iiNcxQlmKaIDXMURruIEsxTRAa7iCFdxIr0U0QGs4ghWcYJZiugAVnEEq7iIVfCY7gBWcQSruLhdBY/pDnAVR7iKkwxodoCrOMJVnEyDZgewiiNYxUWs4uFiSAewiiNYxck0aHaAqjhCVZxkQLMDVMURquIkA5odoCqOUBUnGdDsAFVxhKo4yYBmB7CKI1jFKQY0O4BVHMEqTjGg2QGu4ghXcYoBzQ5wFUe4ilMMaHaAqzjCVZxiQLMDXMURruIUA5od4CqOcBWnGNDsAFdxhKs4xYBmB7iKI1zFKQY0O8BVHOEqTjGg2QGu4ghXcZoBzQ5wFUe4itNp0OwAVnEEqzjNvOLBAaziCFZxmnnFgwNYxRGs4nT6FQ8OUBVHqIqLVMXDxZAOUBVHqIrT6Vc8OABVHIEqTjOveHCAqjhCVZxmXvHgAFVxhKo4zbziwQGq4ghVcYZ5xYMDVMURquIM84oHB6iKI1TFGeYVDw5QFUeoijPMKx4coCqOUBVnmFc8OEBVHKEqzjCveHAAqziCVZxhXvHgAFZxBKu4brMKHlEBV3GEq7juJWDYEwFXcYSruG63CvZEwFUc4Squ262ChwPAVRzhKs4y+0gd4CqOcBVn0/tIHcAqjmAVF7FKYkQFWMURrOIsg/ccwCqOYBVn03jPAariCFVxkap4uBjSAariCFVxNo33HIAqjkAVZxm85wBUcQSqOMvgPQegiiNQxTkG7zkAVRyBKs4xeM8BqOIIVHGOwXsOQBVHoIpzDN5zgKo4QlWcY/CeA1TFEariHIP3HKAqjlAV5xi85wBVcYSqOMfgPQewiiNYxTkG7zmAVRzBKs4xeM8BruIIV3GewXsOcBVHuIrzDN5zgKs4wlWcZ/CeA1zFEa7ifBrvOYBVHMEqzjN4zwGs4ghWcZ7Bew5gFUewivPpN7g7QFUcoSouUhUPP9XkAFVxhKo4n36DuwNQxRGo4jzzBncHoIojUMUF5g3uDkAVR6CKC8wb3B2AKo5AFReYN7g7AFUcgSouMG9wdwCqOAJVXGDe4O4AVHEEqrjAvMHdAariCFVxgXmDuwNUxRGq4riP1jtAVRyhKo77aL0DVMURquK4j9Y7QFUcoSqe+2i9B1jFE6ziu90q0BM9wCqeYBXf7VaBw4EHXMUTruK5l4B5wFU84SqeeQmYB1jFE6ziN8ybRjzAKp5gFd99WwV6sgdYxROs4jfp9Q4eUBVPqIqPVMXDTzV5QFU8oSp+k17v4AFU8QSqeMGsd/AAqngCVbxg1jt4AFU8gSpeMOsdPIAqnkAVL5j1Dh5AFU+gihfMegcPoIonUMULZr2DB1DFE6jiBbPewQOo4glU8YJZ7+ABVPEEqnjBrHfwgKp4QlW8YNY7eEBVPKEqXjLrHTygKp5QFS+Z9Q4eUBVPqIqXzHoHD6iKJ1TFS2a9gwdYxROs4iWz3sEDrOIJVvEyvd7BA6ziCVbxklnv4AFW8QSr+O4dYNiTAVbxBKv4lpIkRlRAVTyhKj5SlQD3mnhAVTyhKr6FJIkRFUAVT6CKj1AlwPdneQBVPIEqPkKVAF9/5QFU8QSq+AhVgsIdADckUMVHqBI07gC4IYEqXjEb6z2AKp5AFa+YjfUeQBVPoIpXzMZ6D6CKJ1DFK2ZjvQdQxROo4hWzsd4DqOIJVPGa2VjvAVTxBKp4zWys94CqeEJVvGY21ntAVTyhKl4zG+s9oCqeUBWvmY31HmAVT7CKj1glGOjKAKt4glW8ZvCeB1zFE67iNYP3POAqnnAVH7lKgF+/84CreMJVfOQqAX68zgOu4glX8YYp3njAVTzhKt4wxRsPuIonXMVHrhLgjh0PuIonXMW3mMSiL4V7QFU8oSrecBMzoCqeUBXfQhJp35nNF3LjyfnADQlU8S0jSUzsgKl4wlR8ZCoBJxqAqXjCVHzHVHBkAJiKJ0zFt4hEbuCLKT1gKp4wFd8iErnBEytgKp4wFd8iErnBEytgKp4wFc99WcUDqOIJVPEtI5EbPDMDqOIJVPE2TZk9YCqeMBXfMhK5wTM7gCqeQBXfMhK5gQt/PIAqnkAVz0AVD6CKJ1DFR6iSCK8AVPEEqvgIVRLhFYAqnkAVH6FKIrwCUMUTqOIjVEmEVwCqeAJVPPfFeg+giidQxXNfrPcAqngCVTz3xXoPoIonUMVzX6z3AKp4AlU898V6D6CKJ1DFc1+s9wCqeAJVPPfFeg+giidQxXNfrPcAqngCVTz3xXoPoIonUMVzX6z3AKp4AlV8hCqJ8ApAFU+givfMilgPqIonVMV7ZkWsB1TFE6riI1VJhFeAqnhCVXzcrJIIrwBW8QSreM+8eskDrOIJVvGeefWSB1zFE67iI1dJhFeAq3jCVXyLSXB4BaiKJ1TFB2a1gwdUxROq4ltIkgivAFTxBKr4kGZ7HjAVT5iKbxGJ3MDVWx4wFU+Yig9cKRswFU+Yig+WCa8AU/GEqfgWkaTCK8BUPGEqvkUkqfAKMBVPmIrndqp4wFQ8YSphs0mHVwEwlUCYStik3xEbAFIJBKmElpAkwqsAkEogSCVsYoAI16wEgFQCQSphk34lYgBIJRCkEjZM5SYApBIIUgkbpnITAFIJBKmEDVO5CYCpBMJUwoap3ATAVAJhKmHDVG4CgCqBQJUgmMpNAFAlEKgSBFO5CQCqBAJVgmAqNwFAlUCgShBM5SYAqBIIVAmCqdwEAFUCgSpBMK9EDACqBAJVgmBeiRgAVAkEqgTBzMsBQJVAoEoQzLwcAFQJBKoEwbwSMQCoEghUCTL9SsQAmEogTCXImDLDFR8BMJVAmEqITAW/KSUAphIIUwndG8AEii0CYCqBMJXAvQEsAKYSCFMJ8Q1gRmEFwBEJVAkRqhgYYQYAVQKBKkEym0gDgCqBQJUgmU2kAVCVQKhKkMzUHABVCYSqBJXeRBoAVQmEqgQVHRHWrwKgKoFQlcC9AiwAqhIIVQmKwcwBUJVAqEpoIYkUkEwFQFUCoSqhhSRS4EcBUJVAqEpoIYkU8PUOAVCVQKhKaCGJFPD1DAFQlUCoSmghSfInAEckVCW0kEQKjSL9AKhKIFQltJBECvPO2C+MJR0AqhIIVQktJJECP82AqgRCVUILSaTAMR6gKoFQlcBRlQCoSiBUJejoiR7eBUBVAqEqQUdPhG+fCoCqBEJVQgtJpMTPAqAqgVCV0EISKQW+jcATCVUJLSSREj8LgKoEQlVCC0mkxM8CoCqBUJXQQhIp4b74AKhKIFQltJBESliLDYCqBEJVQgtJpIRZawBUJRCqElpMIiV2ZcBVAuEqocUkUuL4AnCVQLhKiFxFYk8EYCUQsBJaUCIV9kRAVgIhK6EFJVLBt4gFQFYCISvBMN+0CICsBEJWQiQrSsJnAZCVQMhKsFy+AshKIGQlRLKi8LMAyEogZCW0oEQq/CwAshIIWQmRrCj8LACyEghZCS0pkQo/CwCtBIJWQkQrCpYBA0ArgaCVENGKws8CQCuBoJVgHTM3ArYSCFsJLSqRKuAOgCcSthJaVCL15p0RX2hDZibAVgJhK8FtmGEdsJVA2EpoUYnUOMAAbCUQthJaVCK1xB0ATyRsJbSoRGqcLgC2EghbCS0qkRoXkQBbCYSthBaVSG2wAuCJhK2EFpVIjUMcwFYCYSvBOSbIAmwlELYSnOf8AHgiYSvBRU/EMxNgK4GwleA3zMME2EogbCV4wTxMgK0EwlaCl8zDBNhKIGwl+OiJeEABbCUQthK8Zh4mwFYCYSvBG+ZhAmwlELYSvGUeJsBWAmEroUUlqYcJsJVA2EpoUUnqYQJsJRC2EnxgHibAVgJhK6GFJVLj1BfQlUDoSgiCcWVAVwKhKyHSlYQrA7wSCF4JQTGuDPhKIHwlRL5icJQG+EogfCW0uEQaHKUBvhIIXwmRrxicLwC+EghfCZGvGBwjAb4SCF8Jka8YHCMBvhIIXwktLpEGx0iArwTCV8QmAhb8OHZHx10M/9j30XqjgYFWd3TSh6B9tA5p4OjeHZ30IWkfrU8aODp2Ryd9KNqHTj8Y3dFJH5r2YdL1hO7opA9D+7Dp6bI7OunD0j6if8Jhpjs66cPRPnx6wuiOTvrwtI+QnjO6o5M+qJ+KTXrQ7o7SPgT10xapSAuHnO7opA/qpyJiaTjqdEcnfVA/bcGKtHDg6Y5O+qB+2rIVaSEY7Y5O+qB+KuIKRjj8dEcnfVA/bQmLtHAE6o5O+qB+2kIWaRPjB8Aywz/2fTApd3d00gf1U8Fk3d3RSR/UT7kP33dHaR+S+mlENDYxFgJGM/xj30f008RYCDDN8I99H9FPE+MHIDXDP/Z9tH7qEs8cgDXDP/Z9tH7qEs8c4DXDP/Z9tH7qEs8cQDbDP/Z9XJ3OBzwEAWgz/GPfRTucOhgydEcnfVA3bUGMxB8C745O+qBu2sIYiT992x2lfSjqpop5k0R3dNIHdVPFvEyiOzrpg7ppS2VStwVgnOEf+y6ilyZGIEByhn/s+4hemnhqAcwZ/rHvI3pp4qkFPGf4x74Pl66fdkcnfVA3VexoCqjO8I99H+xoCsDO8I9dH9yGme4o7UNTN410xyVGMYB3hn/s+5DpSmB3dNIHddMW2Uj8yaTu6KQP6qcR8+DvW3RHJ31QP42kB78Rvjs66YP6aYQ9PjGMAdoz/GPfB7Pjvzs66YP6aUQ+GHt1Ryd9UD+N1AeTr+7opA/qpxH84Bcid0dpH4b6qWFy+u7opA/qp4ZJ67ujkz6onxoms++OTvqgfhohEH6ZaHd00gf108iB8OvzuqOTPqifRhSEXxjVHZ30Qf3UMDX47uikD+qnhinDd0cnfVA/NUwlvjs66YP6adxwg1/30h2lfVjqp5EM4RccdEcnfVA/jXAIb+ntjk76oH4a+VBIjIUAEA3/2PfR+mlIjIWAEQ3/2PfR+mlIjIUAEw3/2PfR+mlIjB+AFA3/2PfR+mlIPHMAFg3/2PfR+mlIPHOAFw3/2PcR0gtCuqOTPqifOuY9uN1R2oejfhq5UUg8+wAcDf/Y9yG5Zx+wo+Ef+z4U9+wDfDT8Y9+H5p59QJCGf+z7iH6aePYBRBr+se8jLgV+Z+QXfqICeamjXhr36AjcA/JRR300btKRuAfkoY56aNylo3APyD8d9c+4TUfDHgBJGv6x76FNngzuAfmmp74ZN+pY3APyTE89M+7UcbgH5Jee+mXcquNxD8grPfXKbq8O7gH5pKc+GYES9knAk4Z/7HuIMzxa0NodnHRBnTIyJeyUACkN/9j30A6bcL9Ld3DSBfXKiJXw/QRUafjHvoc4t+MekFcG6pURLAV8LQFYGv6x7+LqZQrfUECWhn/se7h6mUrcUMCWhn/su7i6mcI3FMCl4R/7Hq5upvAoA+jS8I99D1cvUxpPpIAvDf/Yd3F1M5WomgPCNPxj38XVzRQeZwBiGv4x9iBaYKThDRWIMAlKmESLizS+oQIBJkEBk4iACW+X745O+pC0j3ZPGa65C8SXBOVLIr4gDW7L6w5OutC0i9Y1Nzh4FggvCYqXRMRLCXwgEF4SFC+JlhWpDQ7ABcJLguIl0bIitcEBuEB4SVC8JFpWpDY4ABcILwmKl0TLitQGB+AC4SVB8ZIQzKvGu6OTPqiXRryUKJoJhJcExUtCMO/X7Y5O+qBu2rIihV8K0B2d9EH9NOKlRPAsEF4SFC+JiJcSwbNAeElQvCQiXkoEzwLhJUHxkhDRT3FiJBBeEhQvCRH9FCckAuElQfGSkMxa9+4o7YPiJdGyIoV3AHVHJ31QP21ZkcKbN7qjkz6on7asSAm4v7U7OumD+qmMM31iDEJ4SVC8JFpWpPAeiu7opA/qpxEvJe8L8lOKl0QLi9LXA/kp5Uui+4QNnGoRXRKULokWFSm8IaQ7OumDemmLipRIjKaILglKl0SLipRIjECILglKl0SkSzDZFIgtCcqWhIo+mnjuEVwSFC4JFX008dwjuCQoXBIq+mjimUVwSVC4JFpSpOGLHbqDky6oi6rooonHHrElQdmSaEGRwhtFuqOTPqiTtqBIycRjj9iSoGxJtKAIL+LrDtIuKFoSLSdSeMdJd3TSB/XRlhMpvOmkOzrpg3ppy4kU3nfSHZ30Qb205UTawUxBILIkKFkSOuZMiUcWkSVByZJoMZHCG1i6o5M+qJe2mEjhPSzd0Ukf1Et19NLEA4fIkqBkScS3tMEcUiCuJChXEi0kUjLxvCGuJChXEi0kUng7THd00gd10hYSKbwjpjs66YM6afwODsyHBaJKglIl0SIipRKPG6JKglIl0SIihfe1dEcnfVAfNTGzTzxuiCoJSpVEfHsbrCAKxJQEZUoibjKCFUSBiJKgREm0eEjhHTbd0Ukf1ENbPKTwJpvuKO2DEiVho4cmnldElAQlSsJGD008r4goCUqURIuHlEo8bYgoCUqURIuHlE48bYgoCUqURIuHlE48bYgoCUqURIuHlE48K4goCUqURIuHcIVZIJ4kKE8SLRxSOvG0IZ4kKE8SLRxSOvG0IZ4kKE8SLRxSOuHpiCcJypNE5EmJtQYC8SRBeZKIr3mDFVqBaJKgNEm0aEjpxPOGaJKgNEm46KOJ5w3RJEFpknDRRxPPG6JJgtIkEWkSrDYLRJMEpUki0iRIDwSiSYLSJOGihyaeecSTBOVJosVDCm9l6I5O+qAe2gIihXczdEdpH5QpiRYRKbyhoTs66YN6aAuJFN7T0B2d9EF9tMVECm9r6I5O+qA+2oIihXc2dEcnfVAfbVGRSuxLEIguCUqXBEOXBKJLgtIl0bIildjZIBBeEhQvCR/L+ImnDQEmQQGT8NFLE56OCJOghEm0wEglVtALxJgEZUwiMiYcFSPGJChjEi0xUok1+AJBJkEhk4iQKbEGXyDMJChmEhEz2cSzgjiToJxJRM6UWIMvEGkSlDSJSJoSa/AFYk2CsiYRWVNiDb5AsElQ2CRadGTgxrzu4KQL6qQdbEo8LAg3CYqbZLelCcIiiXiTpLxJtvRIJVbPSwScJAVOsqVHBi8ZlYg3Scqb5CY6KX5kJQJOkgIn2eIjlViALxFxkpQ4yU36VdfdwUkXhnZhk2xaItwkKW6SETcldgFIhJskxU0y4qbELgCJcJOkuElG3JRYwi8RbpIUN8mImxJL+CXCTZLiJtmyI5VYwi8RbpIUN8mWHanEuneJcJOkuEm27Egl1r1LhJskxU0y7maCkaBEsElS2CQjbMLrDiRiTZKyJtmCI5VYfC8Ra5KUNUkRnTTxxCLWJClrkpE1JRaKS8SaJGVNsmNN+IIiF6WkSbbYSCWWmktEmiQlTTKSpsRSc4lIk6SkSUbS5BOPGyJNkpImGUlTYnm2RKRJUtIkI2lKLGmWiDRJSppkJE2JJc0SkSZJSZNssZFKLGmWiDRJSppkJE2JZcASkSZJSZOU0UsTno5Yk6SsSUbWBENBiUiTpKRJRtKUWEgsEWmSlDTJSJoSC4klIk2SkibZgiOVWEgsEWuSlDXJFhzh1+B3ByddUCdtuRF+EX53cNIF9dFImmCZViLOJClnki01UokF0RKBJklBk4ygKbEgWiLQJClokhE0JRZESwSaJAVNsqVGFiNZiTiTpJxJttTIJm4r4kySciYZOVNiWbZEnElSziRbaGQTroEwk6SYSbbMSOONdhJRJkkpk2yZkUosypYIM0mKmWTETImFzBJhJkkxk4yYKbEaTCLMJClmki0z0ol1WBJhJkkxk2yZkU6soZIIM0mKmWRLjXRiDZVEoElS0CRNXKKXeGYRaJIUNMkImmC5WCLMJClmki0z0olVWBJhJkkxk2ypkU6sXJIINEkKmmRLjXRitY9EoElS0CRbaqQTq30kAk2SgibZUiOdWKkjEWiSFDRJE7004ekINUmKmmRLjjR+z2l3dNIH9dKWHOnESh2JYJOksEm25EgnVupIBJskhU0ywqZEooBYk6SsSbbgSCeWyEjEmiRlTbIFR4n1lxKhJklRk2y5kcXrOSQiTZKSJtliI51YqCMRaZKUNMkWG+nEQh2JSJOkpEm24EgnltlIxJokZU3SRidNPHCINUnKmqSNTpp44BBrkpQ1SZde7SwRaZKUNEkXVzsnHllEmiQlTbIFRzqxykYi1iQpa5ItONKJVTYSsSZJWZNswZFOLJGRiDVJyppkC450YomMRKxJUtYkW3SkE0tkJKJNktIm2cIjnVjfIhFvkpQ3yRYeObzZWCLcJCluki070oklMhLhJklxk2zZkU4skZEIN0mKm2TcwiQTwTHCTZLiJumjmyYeOISbJMVN0kc3TTwuCDdJiptk3MgkE+Mxwk2S4ibZsiOdWGgjEW6SFDfJlh7pxEIbiYBT/8f/evdmt/+1OZ6bp7/tn5r/ffPlTz+92T6ed4f9m3f/fPPzLv7xus61Nfbmy3++aReyfvnP//u/d72R6/+9u/XeHrua2z4N+7i+tP3Wx/W17HldPB2b02nYz/Xd7XctwcUzrylp/IfddP/wNv5DCdP9Q8vuH67/R1DxH1qE7h+6a6xtd7r2nQnT92N0d5axnVHju0N2051lVWfCGt/9w3fC3KY73cmusdOdCWe7xs53eq7fWY//UJ0J34u/fnIl/iPayriY1zu9OzXXvz5tz9vR7Rne4usL30t63O0/DftywztkVV5Xu+Pr5bj7uGuO47s96Kq7FP3l9yL+97oRIf7junO0+5P0pWZfX6T5rXn4fDj88njYn5v/PY8fATV6BEJF9z+bYY960KHWpd2dmuOvu8eG3sbr+umBTLUp7ve8PV9O4y7NqMvMJ/fe5Xn78NyMbqoYdtjd1N69ZX8H9e2mutt9znR0YnvuztrR7yv2194Gub2DG6EzHyfSZ/Ieu5HgYt+JnYMb7Uf9Zo7ypN9fD4+jyzBwHn2/kXUX5NfDI5IdRrJdbdeMi8jNyETx2NKa4PofPRGqeHChF33g0drfHqjiwQBfbzkKBnTxeDBzqUfjrC5+4rmuR2OjznzQL+fDz8+Hx19+ft1eTs04prHDS7EReT0+bE/N5fg8umFy+EhLn3enHrbnc3P8faxIjRT1g6jY5D1xXZePu+Pj5Xl7Phw/bkeRoB7o1KHv3NxcLG8sQlZSg50czT46b1CCBoAnj0b+zFEa9c053Wiw1nmj08Nz89RcL0fyqoyGap03ID087/ZP593zSOAotO8mX3MLOvsb28dV1/di9Pc6b5S6GU3+lNHwbTJd/9br9K6q0WBt8sanW4fMrVSjUdrkDU0Pz5dR8COHDh1y1R2exo/5MMwLqnsQrx9yiP/oc43rK7y7G2fu/3K3m3kLtkTmc3V4+v3x83b/afyThgFJyByyHw5jNxyOW31+1Un2t1Hsrvw+9mQOuoekA6rRfGYyh7ADdL3R5GVyLyrrdKNJy2SOUcfdp8/nPUmd5XC8C5n++7h93j0ct7QkcH0D8HCiyfupj83uebf/9HxVN7r7w876pLpzTn+bXfqhZ9O7d7vBpdTu6/EwMj2cX/oMv88wb+lkuJm+JZ0mb9AlppNOOJrmTN7YSvsGDjma4Wze4Eq65ZxzNLnZvMFs2H3ycozmN5vpqsOOwbUYTTSZdYlhn8yF0KM5x+aNIY/N82lHRG5Gc8wm070/b4/kSd8MR+S8QePxc/P4y7AXP/xRLvMJT0aOgztq+gFdZjrkTBynRxfNVijlbu1oerCZ1/L5cBrXPIYaZegugN5kPjLX7p4Ov+3HXcphl5m/+trT5XXcjxr2k/kDD0/jGMAMn9jNJvPpOjwfjj+/0L6GMXPInOBjV+fm5bU5bs+XI+nRD3vMfDyvPT5cnh9GF2s4oHbTg7mVZnu3vsVa93KWzXyUe6OpkVGPQgybOQndegUPzyjAsJkzT98h9+CMpjSX+ahfO6ZTwzVjHt/OYfibmTJcj273o/z9+iLhu+f39XTZcwLZl+NljxmU7CID1adIqo9F9KY7S8uuse7DCO36xz30AUbfj+ljXNPH4qZnErYPhKzuTNieSVjfc4K+fOp6/uF6Z3R9Ldz14n0fQPlbBf2WJ/Qhd9C3Wnpmqtpd1t24MOKHj8kmMxDuujr//krSi+HDq2914f+/s6vrcRzJkf9ln+9Bym/dXzksGiqXqkvbLskjyVPXB+x/P8h2pMiUbETv0xRmMJSVyiSDESRzY7Yi6UXHYehOGnhKVcpAvTFYBRMa7ICEHeCwA2rsAFDYEHacSdgB+PARslIDnwE7HjjXR+wJRIcAPBpcjR0QsQMa7ACDHYAP7/HhQZxH/PgEHJuwigk/vqlZp3hbw368xWEd4hR2wTMNfpcJj0cZ+EkLB2qx3hZrYHOENDhfDoIc1sDhFPjsiPFaPuCgAcKHCitncb58g7XEIapwiHCEI/ZYxEaIDbgRHL1kA9w/DhFJtp3WRZyup2VUmleUywiJsYYvqnM2jK1k8PoGe8rgHQ3e0SCLsvAqFnvKRvzRwIPBUTisp8N6Oqynz2kavKUP2L/4hQEeNVjsX3APAQl8hNuMBvsXHzriQ0d86FRh/1p8hUx5VPT+XdrTMnfDrFddiSqQfPFlsfYG4bzaqLFIJifywU+Du0rXIot8pOWDAK+StPgfrNOrIK8SNTZJ2Bta72TbnDwLZsdhmcbznSrVCqN06zUJkqauXbpHEOqmqTiVEs2wKOlhES5zb1R+bxYh3Ywu/VenE0f1les/+YGrrfG67H+dOhJkjL1OUzcsl/FbC/nr/SQCEZAC4Ok6LW2vsx5pBwEACAc0jckoRnCHf/RIq54pmYMGXg6OB8/MwGRjrCKJoR7PfOoWFHMRye38MPri8HrFWkRyz9ztPvutXuXipJIFm3vn5VX2nehNuJp79eYqi0qcC3/v3q6q0EW+Km9hd85kGs+bma+nU0HwipfiQsfN0Hc7aaZGSHykldWPFHxHEOfUIQXxZOnYavH3RSP1RjjglMtF6E93brWCImWnBknT7VYj0l63QNHXclolI092SOTOVXanbr6MQ5H6Sma0IdmofYA0suKgQWFGE5EPZpmvIrHs/RFFFig5rwYws8kueb30kbd97meNGCRz37j8y3ORickqgfmTd/hqTxqYyMc0nI+8W7r9X2o9ZI1druPL4aKq/sS6JnwlyGtIT/6ws3O6RoK6JrGuZDM2dX9du+JryRjWNFxYeNjcFUtICGBoD7Da2nELkk5rcgKXhZ/13lre+oE/MDLGNg3rUIW1Q7As+a+GPEX9fESAyApLgyTZIPEz8AimebgyizzNgriwIDldlZN2lNPCsTqwUQ68gDeZPUXeCJrMgyYLyGwDksyANDgAd0VQVxF5eAQcjPBiET8+wSckl1M7fHNSwrwt498a3DYSTWQQWpMkOCw+EJWudpa1kqYCp4LwZ3LuXoGPxLJaLKvFGzqk4w7Zs0OC6+A1HVbKgwLx4LA8OCwP4iEgTw7gbwJokoDCgwieIFp8FSDnCA4g4ccnkxV/IHoEi6Ymffg4Tj/GS1eI1TJ5q2hT17dzd6/92kkUQRGcNYkaSgVH1o85srL2/XqgxqvstCLLfruhrMy1lUrnDfeL7nZO5/H6/tjD2sVKZ4Uz3iRuybrhAAkGiQTBDSXu/D4Mdu9HekATpWVsz8Ttl4flfhx+/Op+a7viFCeQYYkUb7rh+qXJdZkOVqTqvss6xI4BACG5oZup8e1fRShZL2KXEiAXl2/Grkt/Vn4vSlGKlM66v7th2QV4mUA2pLh5s7R65PKYybSxabif9dF+Tt3w2fU6A61UYksi4c3WziOtd1lIgxwE/DiP43Q6d+3QDz+nca1qWmcGyUxZyYMkGDw0e5TdK4kwcdvv0PirXF+RqqSb+Jj6bng//y4xfK2+G6KlAfYwAdohOGOLIGmBqSx8oAXOcYh7DnHPAec4wAmfSWkEfw850ENQCQAIAXJgQDtUAEiLQAERKlWEo4sAexHRO0FdSojeKTtwsjblZ7e8tXN/6ocPXXclw4Il6yB+dsta69Kelm7q56U/FWBJMinQCgygnsltX9AcLECOBcixwBsOWqBDJ5cDrHSAlR64xWMpPfCuB971oD4CyMqAfRCw3AHCS4TgFy2+DQScCKk2Vfg2JhfI4T9hHzQkHvnZLceZai3LMQ0arwx2p8kyHSRPixWwWAGLtNYhqXBQpRwQoAMC9Hgpj8zBA5p6QFOPzCGAVQk4CQEwOEA8j8gcIopjI05ChNyXsA0S6OKUK05xehtSO8grqTekZFkMWey0mdr5y1q2XhgSnf3slv5vjUYEyEu5zDJxEeNnt6yI+IA1kAEohayF0m99Gee+BLa1LCKxpMb3c+oK/C9Lwhuyhvbz+mb0+0nngj2JbXL/Z20yl7PVjpLwcX3eU1JdiTskdL4ZPIi5CuInbn+vtl6FWCVQkDvp8/qmVBZ1WHCgQetBeDWZmeFX4amuEpT+QZJSn9e3Y7JT8oTIlZssHVc1bf6rH3qF1FWLBv3al7P+8krzIPtjP69f/fuuK1e7IXjlxxtDeoMnv11b+TgKDeeytqfqEyiDEhgHsKgglcncVzzi6e5QSlbDpTPS7v7sqX6xuuHAtDD54giqxq+aJBo3008XQcF/UpcXZg/WQGF+MiPbLL5aAgX0yfTsbnn5rXMp9dbkye2L2kK5W4EUDXC0QYA0APgWANEC1lh4EQvGzeG0OdAeDoybAyHqsyoO4OtRJONxEgPAcUB1VsD5DaALIxBwxEmOAJoReCvCLyewsAnINWUXiKSksVmVJ6mufjgSFkWs8YBwnjz2/bAShKdWESoqxQU7U9ckr55NdlP7anOqEE7qSGXSJDY4+Ovcq0KGr374mNqpe5+6r3E5ENVkixBKxOqq4g5+PyzdNLTnQ6HByfCOWkDsY5OTYuSnFtvOIhWwwFQOW8ohz3VAYg55kkdq4vFFPRI4nxM45O8BgC7gzAQkiwGRJSIBj9AaI85MRHKd8NCEapCEzDIBIzZkbU4/Hci2CmhVZArez+00afk7ydhGVsb089s4rrSLMiQjGlnu0s8f57FVuyPJ6EUWuKxzR5bup4YmSZ5lUgft5z2ZmWSUIqtY+nm+dKc1SqlIoGqhyTqAfp6XqRirkqQHIVXPMvMTXyuB2EhkNdsvzQwq7o6czPGrror2O0XOkbM3fnW/fxTBVipwCXEmkRV1v7rfl2JYkfRVoGuQ0SLFg++pDZnj3p/z3i3dWvL7FHEpdZskxu6ml/F6+lSrK7cMQv3tzoA/NPoqsDXq99Kf8NK+v7CqZggZMvE/t/NyvbwflkeqDNVwC3Du2kLMF9si1+Y/tgXnRFfuRAuJwiRiD5ATSllyhXnuNMr5cLXVPJIxev0Fa0PNk/1nVNpT1eRKjadfxcmWTVzgWcFYg8qrAYfraqujJCuOHo98doxUFb0hIyVs7rOWqHJwUq55mHu1zVVOToo2N/7t2WvL+GfIzOWY0LNKVH5ANsrWqxcOyia7u1QgbOQ7Yt8YSBUGcobJ6RMyGYvCBwsoaEGZO2REDm7SgXtyIIw96ls8QqcHk+3BZAdkeiFTWGDNA1jzgBAS6yzBAEmCz4hIwxIemuBxUm5LANfSkNTyefx57v7uVDWV8LOskfHy+J8VNyNr/ci2/K/2dDDhz6q6c0NO1flqh+tHe1o7P6f9cDup25Ilnl+tfsFGjaIjW9K/2v99+70UtXqN8rBkI/pXN89tMXdDdrQ3UAyb3NK1BYkql1z6/O98ZiaxL+uarIz56paCEJR9lOAYIEYhQNn8wI0uJ7vObg8s+UxZwYtcMXdJ4RjW1UYdkxVe+WH/Um3SijcnR3RlU0/dtQJ7f7L8N6sHPluhMVIHzAYLwljaIqeHZVMvYoCaK8B259wNa4ghZR249pBpZ2yyjcXYuGkyB8dDT6MioqWvA7sQ84bDfnP5qJFsrHjas/2i8nZWUZR29ztGZfCsqChMvvrQCt2QoBumny6BQjiG9Z4Powfvr1CO+bNP9erlFdIhGx9udp++uYqLZFH73eLBayvPQ6pKN2Ov3ll5H1Jj+tINXqZRQ/XIWSpf/XAQaNUwPHIuyFpYpRBSLdUAA7diEM4MMkADKGpRoGDBJlqUg1jkdA4ClgNcdfAgDuHR514zQEiP+OaR9gUUZwQkiQEQMqCWJaICI8JJRhQ6RNCcEb4xoWA3oXIi4cc3wMjNhh22oUw2u7st0GenWJPZw23xn9VeGTmpq/Gbo89/4SfXNZlZ3J63r/GSeT78uYFxg/zc4ENZ0McWH8qiasUi1XUmU9X4zlBRHCCKz3UFoMU9wpnH5gqgzoPNSTXyCpTcRPDjMUcn4L4IsBfBaycUHSXw2gk/vsHmasIW3fJfbvu4pBMeb3MDdq3X8rNiF8UctBGzt8kUmYEz5Bhm+eBnzlXBe0PKScrw3scqoG9I0UvafOFqlZc0JP86rINVfpzbRdOERolTFYkBhrGoHlfef+tqMpnjIfndm+F+6Je+Pff/p8l09ZnIypqbvbUwWEcHRelUZDgdxqX/KDoJpVciR3GOg5rGrt5QbpptpBC5duPw0N4+2+H9XA5Tl2QjDpbBOTZg5wz8kQWHYeGPLKQzi7TOgZZwiCkOMcUhpnjY8Qh2HpHBw4cG8DcB4SMgsAbofhEBKGY3AfkzQj+M8A4JJYAJCUDCj2/IaDQOW9PU4XpKihM5tsHjDDJgg3WwkO8t1sGCN3JIWB1YYAeX7eCyHVy2N5l/wjLCX3p8uwBFPiBuBcStgF0V4d8jJJMIuTKCPIuoPUjQPxMSm4Qf35DR9rGeZfeUPIfbqA1yrnnZ61PLGRo2156STOh4mx7WPbuNQM73NOTcqb3J/UB8SeQYUo592H06UlPqc5YcVgmbB2MXZK2cY8/P3VypedSNeN1EcoXCVik0SLeWyFz7Ye5yLjr6JSETcm0b69XvRlfp9rL7IEb2VjVkjB2vy1pdsiPc5EbMZzcDcLB926wsHOLakGP95YOfQiaV3pMjPZThA8iksnuSqpU2X0EmlemTU/xXb3UeC3lYsWwVOQL/0g7rgOmi+EjVoLqMbEmCcbNp1BFTIp7LH58k8Tarr1ZT8Rv0Gkztnj2W81WavAYVOWE827wNMNWm1YfKPLchK0xulgvQqMYek/nHpZ10EZuCniQvcTNymbq5G9a58C9ymVpSeoEMJzfzTwwqlTKjRGhoBlKVBYSzgBw2ZLgIeANU5oAiHNJXB77C5zn0gKYelVYelVYB8DVk6h/ieMhz74CpIsiWCI8YgYUisGUCVEgQMFKW9sH5NGRaWK7lj93MaQEcLVl+c7ndO1BQZWo3ktNAbvdYaMgkf06urSNB3aWbTt2wFNpULQs4PGr6PJnFXLqpv3x2U3vWh0/xeSS9WIZ4VYOdr6Qx5Nj61VpZny9HW2QfU2VXTl40AstadZLj33PBkduUNC5AbrafxnLFLZP3eGxmX8UJRTSTF3jA8qshsEomrkhckw0fQA9FXpNDs2GvbLKR2BtfLdOUZGXxZvvJV3PqLjxDTmzdzD7/ak7N8jQk/l0t7xfWqZZZw0b18/Xnq9+nsCeZiu2n0kkc3ZCd9DoG61o46dYRcvDVgcJ8ZlCzNG7Ie0Co8O9U94Ih73koTB98RYWeyanc2uqr76nQJDmh+2ZdJ1nSXzZkkcZld8ekbKZxZGJzuc6fR4OPlAhasW7lZuxg/JdSPyt23wtru6tklP5ZkSv/17Wbfh+MO3LqNh9DjguQ1o7fWrl6soHzr2tf1Fqq4rOKJJimrn3fzzqWY50sVBabRwrn9jQ4/YZUv6fihjEZSRqyVGhah93N3/1y+qx1cYj4zXkaD5wRkBDpiuRDDg+0AhTkBHBp9KLSZDn2LjfHb72g+O3sIsvHHP56BVrIDafNPvXO6oSQ7Fdheu+d1UWphqT7pNVnP1dd1mnIi2mU4YMfqwABeSvNvWFJIzaxJ/IMixxcsSdy1k/G9/uDnq6HAh5khLmb3M2mUdxPRZKqa4zpSzehqK2KHJgzdfO1uAxOJpQJ+UYiZ//eZrH83Z6u16/beJZumpX/US2q2x0wrFc7sK4aUlSrKutwDoyWdYaqYdVnLo0sTHn2hKNjoXAbSQs9s/8Ca6krrwzJGhw95+gdFI5jN+KB7Ve/X4UWcorWwTOenXDl+0l2ZppnxQkY6ZAbFmpczwXuUUOzWUd5HZbxMmpEK0d62lzrThZuPGsVkbGhQZ7bbOU/5NrN3bLeslpOtKplC4dH+uTJtZy75fgWvFpOqLYQku02aYJdk+V2V82TG4dqObTBQqKxZAianw/mkaVJkHgNpHeTy46g7Fo4cYuyMJsywYeKJIBBB5rVgWb1gIUen9cD43p02gbQoyG3yiHFDch+AwSoiGKtCP43gv+N4H8TuLMELTyh4CxB3W/IQs25W4phfEaSJglvk8j+rblb1k6D9rzfrUbuVtRvkcnjarY0KFNZg2IAVrqYu2X6qW+u8kozRG9MbmskK1TnbpkvnYYftVWNcdiVZPvtanGfXykqBUQ8WaQzd8v1cjicW+r3+TIPQw6ek2YP01RFolYkatqtppE0UkPCjHlpp2U+6eZshQrJ2Su7T2Fk2tiETZ3joO/BoCjV4VqRifHdzu7aOXnxYoNiyQbuq2k2On77K/OwmZuryUaJeRkvu0WWiIecEnNcISDfJc8YyLNzwBrm63u3HhdDNjpvj32KfVRyyu7gzeweEBqVmJKX5WwWX8BAozJT8rKcg1sTxPYmd8EtsX0bl7L+UV1NQv4eYetg3oMSTyryeh1pc1fNLqX2/8zas/JsOd2edQ6l7dKmpNnIKQzZ5n45lcJDzjLK5nYrqW86+cMXXsvW2kuvsZ0sJySb1bLB1S0Nhbqh3rcmu/7n38PpupzKDnqjurYqUtQU6PiFlGeVjlWTjey3a4s+5vbrUmRNaqZERU5QWK0VPY2qTZOURJfx58+iuE/WoIQ8NoCkWZfrNIwfHxptyTJe8CgmZcSPXpN8aRsyMo/Ez+fegW3mQJ53A2bY5IyIc4u3n6qLBiV0MKjPMGhQtfgVFjUlDjSeR7jzuRo4zxBAJA9orYgoL27IkoAdEadieEUyCtfhfi3vj/bcTnpCt5qJUZEZ5XXo15nT7XnPdKrJZiS5ex1+DcW8eXkfS+4431pmADC2Cwy4PXoddlMtpHyckFonslrhbu9wYdVYkIrMAe/2hvE67DsfpDadkP4mUqC/DvP1bT5N/Vv3MY1f+96AWtJhBvm2AYlogFNtnY8ECqZQPG5TJmtwnIENHVJ6hwosDzs+HyQsvsepC2hoCrlTGz4kQA0KUKYjkqSI9puIZCyiwyOBmkk4ogk/LDVZ/uLARnEztaR0HVlieB8A82P9ID/m9fK993b6/WO3Q9V8kIpMfu+21/BV3kljFRglG1Pu5o5kVKtQMzmzXJk7SlCt0vBrsvm+eFWrpKbtqj12Mul1OhcZgqKMSdLg7/bcvxeZqkq/yeGasPN2/fgoiv3VtB9yg8BceWdDreb8kDQGjB2PyajVgB1y8WHySdGemuNABlOYnNqhtCa7GkgHkK0d8SuysCXlKUkkrs2WC1pMHjW27w+29kPaaukI2Ja/h7l+HHYXYdRqFBmJJI6urpBtMU3u6CVHNX+3+vYKlZbm0bs1OaarvHBQjiMnDSzdhDlqCidJD0DKJTdj66SvI4PO6NnL7AsWJp/RLUaJyWR6v7d+wLooKZEsAd8ZfkW+KA2RHPz4sPfeLW2vY4oq/6rJkSAPc7fbWtZBpl2R/9ZSyWNnoeTwuavksrVO+Mm90H/0O3FQzdyoyJrY7375fFzVq+greRZJfu17fNrhJkd7k13FytpBc5v8CmTy8j2+nfvhfe1C0TKmdNYkbf89vl3P2ufLim1LiqDf4/NWO1WkTbqd8XHFtrYkZVqS1f0ej/r1vCqO4eLQ9/hZ3ogVVMpIHqGxvDuhljUUjuSObmb0PcwyD3akMrKa+dJEmwwTjgTXdzP6rWQ/gqe3UT/eq2GXT21MbCJP5jrf4352aS3H9nmyQOl7LGdd1rJY0pNs9vd43MVQy1r9wMKE8bi4vpZMZCAR2/eIUmRtSmzvQJb5fY/PCixrWesbSKVWm9NVj7Us940kHbMaLAmkWlb5RjZ0HW9UOdgosrErmyqrq2pZ2xvJYiRhruiskhpMJK8IUdaKUV+1HGqRyLmf3+P81U7Lvu9ZqhlkQiRs7fqe5Y3Y/Mqt2pq2IwVecoDv9zh/d2saqeC3hCJkqUs2VHZVKQ6VdWNTX4jXEmE3TOvJP//rH5f+0p37ofvHf//PP//97/8HQNrpJQ=="; \ No newline at end of file +window.searchData = "eJzEvVuT21aWpv1fpFtPlyXVoavuLFnu8pRsayy5fOHo6GAykSmOmGQOCUql6fj++xc8Yh/W4V0Heq7sUAJ4H5LAxl7P2gT/+8lm/Xn75G+//feTj4vV7ZO//ftXT1azh+HJ3568Wd+/GT4NyydfPdltlk/+9mRY7R62fzj/8799GB/2f5svZ9vtsH3ytydP/r+vzkd59ufLYb59/fKX/5CO8fR2uNnd10f66snjbDOsxhKDPPrrn3/+6Wfx6MNms944j/79j9/9JB58sbpbO4/9408/vhaPvVqvBuexf/3m5x/FY3+ebVaWY09nxbvPi3H+4eV6fPnm9Q/r2+706P6OniffLDZvd5vF3WLYQId8OltsHqcd6JfS02rZ72c3y8EMMJ72ClG8nI3jsPnyarGZ75azcb35brbCSG6Oe84ve97N+I8XpVkuVrfvF8sRRNhvPh43j+Wu0cR1OOvVsFguVvdvFvcfwND5cY/laY+09LebtR3gccMPPijDernevNwtb8D0/eY3x82DuatxNh/fDavtGrze58ddtuddYvm7zThbgJfX/LJxRuYLU+iLaOrfdzfPscQPxy2jaeDr+3DcMpj2sLg13DI+lNsnJcNvbrlDKPsfz75+u1m/Wj/crI//ixF8fPb142Y93+92/N8wx/DlcXYLhp+3TUh8v97NP1hix9MOoew36/lHLHR53DKcBn+y+8CEz/OHYUQvpIfTpvG8t8vd1pD5eNw8IRd9c4+xSe/u/rr9CRwxzsHzdXjE+GE9LtYry8324bBHzr32p914u15vDKfX+rhHyln2dnkoLoHUx6VQhhrSflisFv/zLZ75sFgt/vdjVvIv72zJ8evp7WbYDqv5YDm/Hk/75JxhPw/L2Zfjts+w/M1+j+1lj7T0tz/Y8x8f4gQP6xGsWjfnbWOJ65v1+M/ZfLd7eLUcZqths5+KwGP5Zr/7p8Pu8+Pu+ylJwtjec71Dz4gOaRs/MwiayJu0fZbxHr0bN4tHQ8273W+fUvH+OhuHzZth9vHbYRzmIzpYfN7vthxmH2+n3ewcgsP6cf/vCsp+myu4rMthfT7rQJ7itEgQo9fiaTxuayKK+S2BCnVcBYrdcwn5uusqki2+i8+0OK8p3Oe9MApgKk6DmGblAgvqwAoKuweT8g0urGRw+TCBA3NiBYHVi6nZqjvqwg0OiU9HHNmUbPNkYqrh9dp8mZSKOrMy2+7NEALTm+7wZzyD2aFNJAGPJvBALq2AMPo0LRlyam280avxDIhbm8Jtfk1ONX3yZs/GZ0MyZEo2mhAlFylBmmxb3aHlW950u3/T0wEH1wOYPJzAYHBxBYTLx/EUFic3Ufi8HE+BuLkp3ebn5FTM0dXZVk+nE+iurifIuQ5tzq6gcHo7nsTi7iYOn7/DKHSHR3NYPJ5Egri8ksDm84Rkr9MrYOJez8Knuz0JzeL3bFTRN83q+Xg63PVNPB7fxxOYnd8EEvB+Lc/zyf598/b716c1gUeO0yH/cP6DaPn+9Oz55Ujz9Wo7bnbViyIP9rTekn4NF64C++vnfyzSbgc15rYeCcbt7f9YbP/HYvVh2CzG4daStx1n4277Sk89bthl27N+GLbb2T0W93DZFk+sT4If1+M3n2aL5V5xsidEt1HWyUEfGD1RenbjScPG204gkaN4u1++ef1qvVoN8/0stuOp/pryBvdHhN7ZGnOKff71H6fXsh+jN69X882XR/DVPD3sMpS7RPKPW4Cv+bRpIO92sTVEVlunpH6zXNqCZ8tlLPt+GKeNXq13K+iV3w/j/PJP89NeAYrF9rTNcIvEX17+wGshKPdhtvn4+l+PhyN9a/rs93sOpz2zzoPNMINe/mm7QNJ2WN2+Wj88zFZQ4H7z+WXzUO5oG022w5g1lmyH8e2w2S6247Aqzvn3i4dhvYM+8+0wPl6OMJ3/4+UIEbrdzXa+WdwMP67Hxd1iPjs4EIjqvOeq2TNAs1v5eYp9E4k+72/JSPx5Q1tWcwPX50vURlm388B8iWS3zJekeMN8SeOo3+5389lqNZDvxelPWW9teTj0DT3TcXfvYTtu1l/UtGk7b9L9MH47fFrMyU+tyrofxtvzlpG0/Y3t07AZbo+55PXfBV92ur3s5GVYbA8bLFb3avJiu5029eZtx9lm3G+jxh223M6FtRlI2voRDFs/BrM+zxbjd+sNeP7st75bbzznUHlpn6YY380Wy+GWHkf7TVIudeaw0CVPUFtGUD7aMH5aGC4zmS+PFprL9OW4W/S9WG8W94vVbGn6mJ+e95K/uSpTVCdcM63jaKjNkk489tDgyUe+AtsJKCGYTkILy2ka/EN/k5CATns98HcJnaI4AY7j2w+z1eyemE9Uf035uPsjQp9yjckM2bPbvjgj8o6bBXIOxgZ6ZacNI1mkYSDfRUkqQFn3A5R03CyW8/LLD9+8AsNuvjzM5gmJ5HDPRYqDPJr5/W1/bdOBi1v+eobSPsygqONmgZzlYgudJKftAkn73uUn6AO7bBlIG9c/3fxvSmUReeN6fd7WltgPvD+ux+/WuxUz1yO2SRyE++MahuIa3HK3FcINt1qFonujf/o0bDaL2+HdOBuHb3ebxepeaDoA+yR+EHqO4YORX2hx9v/5+bM/Th/VbD4uPg0Jb8nT45Hm5ZEsH6mT/1h5CUM8QH48RjfyX415wU1XANbF7e/DeLz1OiHb+/bVKA//cWOe9r4KZzMj+CbtMrsfxt/rSmtnUrPtYv798eFGfvib/VG6RyRdj/rw7aLF+HIzzD4Om2/efh+inx+PdnM82uxx8f/kVbx88zrxVbTf5rriq5gq1M1s/pEtPMFXMZmZy9F+j1fxbcIt5+Kdr3nXabi/my2XN7P5x7/PVrfLYSPX/thruDsd8sPxkA+XQ/4er+f7wG30UHr9XpzRIfN3HC356hxDveKdvyH9MXTrvx/G3/Hu/+6wOi1Euz0f4uq8H2bb0F3yw2z7O90XP8y2oTvhh9n2d7r3Pa6Xy+/vfhyGW2LdDsy7P8ribnU+yu9CncH8+xFvhvv9opNNc6vz458P2Nzofo/XUiw9ejf8n93+Cxb+11EsTNpOB/tdXsMPu+W4eFwOp9cSGAb3R3s4HW0+He13eBXN/Pv1ar9WI3BVbNs5+HA54u/yai4bfb8ah+Vycb8/IVJe1eWfFsWRf99Xd774M17P+br/fV/BD7w/xbAf7ErVy/p2M9wNm81wmyE39gsHz8f7ff3Gdhh/HsbNl4yTZrM/0O94xuxW6fe96ZD/D+58u8fb2TjEyqbjMcRHcdsIq9bCaeXWF6Z9U/05p2HQHxLrDdSkpn4NGWkZV6BseTkMBYEtheHTiw/yp8dh9c3b718tFwPRba/+mvIx9keEPsUak1sFMT3b6d3+Jrh69zgQAxmBUDzb6XDLW21Pe6bRkDc0laS7i0Uo3u82q5/u7owU426zWh/2SqTob5AABL+mEWK4OT/V6tVyvYU+i8tDreanPTLS91ubwtfHHTKy3w3j2/V2Qc5QJIT9pGTaL0Ky3s+Wtn0FRKWv9zOhLb9qA000nPc36zHlfD+nYm/zKTT43p6e/ASf3aftE87t05HQM/u0efy8Ph3o7WxnesWPp+3jycbr6bRX2tV0OyyHcfh1uPmwXn9EAI47fL7sEMge/jXMd+Pwbj6soPf+tP32tH0g+dhFu1v06/yJ2GOT7LhxLJNZDk9nKqvhbZnQaHkJDY6XUyqzbFDMVlYPogSHswp92dvzxsFMukPBZPa9CHPm9Og2w/Rw2illdjgdznCTnHZKuVc2DNBI2iAEx9HF9tVyvbt9N2z2JzHnPwiMxXa+33F73JHyHWaWwwNG3g3jy83+f1bgXOmw13YYb8q9EigOzwC1AMxPO2Rlvx8eHofNbNxtoMujwhirfaNEhgvksH3KtTElQ5fFFBy8IvaP9KuePiiFrucfxWcPwom/rJaGzN0qnrp/etj79f39Ejq79luP562jqfjpdIjNOJsuudDJdIkNnkv/ZzdsvhgmqYftU+ao0qMLiGDk0QVg7n6l4PDLz2+w2P2KwGG/XTR192h4nw/bp7zPR9NsiD7u4M0u9eW5L8zMzus/pwhM4pCQwWxI/cvRKQD3eliUSlhkTvE4VvahJMTScYrAsLYNTaYWhFPRlhVgaDa5zJsKN63p4tOti7cplMg6bZiMX5LNINlXX8Ms+kJrhsm/ptrJRi0ag9gsq8VwNnVRNMfmXv8MswlLnRmo1LHPt4CZIQuuVYYpiWXJDFHKKI0sNubyrzIOUEuIGYCcewWyMJgBuM79gpFpDINxZS9GwSzipRCM63XhfHSUNa7CxfLFBbcUhWttLc5iJLkKB7pIiIKKrgbCCJElrxRdZHUrTqYuZOXQ3GtWUTZweSrNF1yJijOaFp1yrCnrS2FmbSkpQ+ldNQpzkQ0TBsa0FhQmQJZ9MkCRFZ4wn7iYkwFzrdvEiPAlmhRbfDUmSHkwUxjSeVOr7wEXevKZ4ppONrfSZucHw/ep57/kyLLqaJgnu6ApMoq4+9RpWj+cTGqfdrTaPaqv6rKZM+f8GET1BU3bOZP2Kodd7Nmk7fXN42J+3tafKDy1s4+8WQ7by8b+TGaFSJ+nrA5Rsxb7KuPy8FItcLEvNGbF1u7Ul29eG1JvlkNC6nYY36zv3wyfhv7R403kdhiX6/vlaVM8jxykOLlf/z13wDLr/QY24PcpBFGkujgko08RMFrLlU05fCqz0UOuLNLaU2HSo9bgNNrTU3GdeAHzzGaeCtfUvI9FcPEMBC3jfemAfWcoZP2eQUOaIIgGGrAzDDtHIyp2H43k1BmM2OjjtOgMC6DRfVyUN2cYfCMjZMq5xJyrlHTjTKRzRIZsOBOZNCpz/ptJVZaTgrmc8aZCCeXtS4RHNkJyOxJlq03lslrbmW7NzkmG3QmFgagTBxPkqikeTVY7WXQ7zcGIetpFg/pomggQ0k4qm4Hm6GAF7aNUnTPDJUlnHwltmZl4cTk+ngl5ZQZBE8s+ItkkMyisSnYwGNwxRYPJYw+XYG9JEEDfssmkGqG/M17/OVeMGL9+35Bavn5PRyLXmPSF93/Olovbw89M0e9d8/eUN486JvTutbCWt48JNbTCwPTH2Wb2UP1iuohQbm5+1cUH+ev6m+//vrvpQk//nvLBlceCPrAzlF//VZHu9ZMqh6D/KgLHajY1m9B/VaZhVZiaRem/KsyyAktNI/VfFWdab0XkWfVfFR5Zkauz8PqvhbCvwdXTdf3XUvhX3VppqCJZprGsBwNoVP3X0bhX1uo0gv5rMXJGH5/+a1mCq2d1LkL/tQyxkRHRf11i7lVK6b82MjgiI/qvjUwelRn916Yq2k/JYXRfFWJc2aonqiOZcS2rkijqvirXtXoVSEezc5PRcrfCiK6QUpgQ3VfxRNakAiyq7utg3KtQVRpQ9zVEwXWnAJVJ93V0KStNdUpN97Vc3rWlOgmp+9p402pSPRPRfS1CZP2oTiTqvhbFtWJUYcB1X0UTXyOqcfG6rwahNZ8tuVEd0wP0qOzpr1naozkiKj8KzJACaeMjZSvCJOuQlsZXliActBpp821lAJLLaJI22Dg1R5I5ZdJGW6fodLZDn7QgQYkCcYkqhQByCRWIBNIqBFFIrjjImMJEJTMWKxgZolsosoh0gchk9UIgZY50bg1DcMVlDMRIKxmCJ2NEBvUMlX6NK59RNUR8yl0B1DZE/FXuDLzCIQh0kaNn8jqnDbRLHSgdHEHtgkdP1zRPy+CVPRiJjeMaFIbyp0VKKIF0PlAFtWxBIYRxIVqIAovIIYQMV0Q9XVwUYYRWXUSRZkkjiBhQRwRjQCCBVMwvD3A4ys8NoLmcviIyxbVqaB6oroj4oMBC6WzvyeNhh5R3RlNoRLpXpOk8I/OoSYJDe8wkngedCcrjJaE0kyxsAVKUIcBIf6ucAuq/VJ6UjpYTPnmpU3waNou7L69X882Xx/31/o/hC4Jz3G247PbxsJvtfGFV6tsfnv9Jhthvka9UL0e1a9UDcpJanTByhJbMhirWiSoqH2QeTbVOHN7iXs5XlesE4C6wZQJdvU4I/iK7ZQgp2AkoTcMqfKCKrcCCOlYhMirZiixJy5oIVbEgELpVg0ZoU7Q1YY6mVQhRVVuhZY+YCcq24svUtgqrpm4rrqwR3qxwa4prjRiqyq0w0u42ZqVbYVztjoOo3YrEonelbETxTsERzatQGEbkiO6VKHDlO7HEta9GZOe5Fo2rqJ3QUstaidOsgifGNB2s8dmUcA2Yo4VlQo8aLikz9bBG6lfENXG+JlbITaq4Yk3RxSodoowbLIs2VvJ1TVpl45JUyTUr5AojTSPrlPb3yKqTFQZcKVcUca0scUFqeeIx6WU1Fz5TLJpZSnWq5gkkWTeLrKD0LeCC4rehYaXre/KRhf0m+dp1Oqzdux6pk8RrAZLjsBQ6VL0WXFGToBBp8rUg8dbmCoGqXwsEd0WsMOgCtoDw18MdRUjBFkhpDlYjBCVsjRa0sBqTUcPWbEke1saolv0So9sCqIw2Fdsw5rhYjRGVsTVc+hiaoGNrwkwfq9FqQrYmSxv1zUq24bja+KFK2Rok7x5k1rI1yPXuQ4iYrVmMvxyE0yCqtkCJuFqNwzJqR2ytyIHr2oIm7mtVJgfR1XhcxWEBl1obiqRmaVtQpllbldCmbRvEHG+rMHrEbcWZaW5VVr+6bZjz3a3GbpK3NW2KvdX5EH3bghH+No1Il5U1jfVb7TiJWfHWYGmOF+B0vG+M5U2jwrVvzRX3viIZJH4LIsr8JpLgZxThgnM4nHK4QEu2wzItsCK5RAssSwY4TEVZ1FOLPOZVygWYtlTZTdio9M343Yap2U5/ylLn5eFQZX6mK/DLh4W+/u6716/ev1PThru7YT6apm19skPSVxARuanSyFK+4vCJJJWAlvBVsk3DqImMdK8ijaJDzeQkexVqlRpEqkOqVwhBma4TiRK9RXHJc50BkuYtS0iWW5kY3SIzGaULwIRI8Y4pIsN1JlmCtzBpY5ZberdEcdmt09GSuyUJj6qg1O5y069nRmK3wfExHZTWbXD+uM5L6jbbLqeVdF5KV9F2Ga3nIqOiXT4ruZp0rtK9shlgMBCk5xuKygomoZRUyECJXFEF5TFAhEjjDikii1Wm8eVmcf9hXA1bBGa8KbdOpIBVdQsUVtQA23oJFKAH9bxc557Dx+z3w0P/M89c/njc+BoMw2Y27jbIdTShTPukEhmbBT1eUpNAZ319UAUI1HDeMjEdaE20GIGWhM7DCewWwqqs9WRQ9LcgQcGvc2kKvQXyqnOFRFDmFYFDlSPJ+mdhV+NKrkmJVygpKlyjE9VzjeNSzko+qJorkKBiJtxspZZfLher2/eLJTWYXv6WJJfr44F2eQKMSN4mOmDdAB5R8zYkLmcCMJCit8k2OQkgk1a9TajNCwCpjOxtYo1WgMwtL+X5cr0FYs+bmc7uLufb9WfgpD5senvcNJb3CzUzptJ2j5EsTJk3uTFnjjBJ0ryH8VhzhALR5j1NxJvbqWhFpFHZjBFEBahzgirgzhEqUZ73OHl3Aq8+75nC/hzhIwV6zxK/W2EKnUjOv7ppid5HJ9wtMY3eR2ffMSWR3qerD+BQ81h13oSZ3TmSDI2MZnuuJq8fB+AWetrK/c4+znbI3Oe8mT9Hbga0cb5uAERhYcgnwEvqBideUatsWEug4Yr1BCAmoClAQAW6AgAVLOQ7srCRh+iMApigTDLACK0uYXs+v4VFiBgN22MYPSyS/Xa9XWD1016/Thu7x2ZY/hLxIfuLkCn6t0dy+l+VxaJDG6oMH6rzSUK0BfIYUYqgEZC7JfWD7vt/ztKO50OhxnFPZF7LOqVQ61jFBIfOvIRFXIhIIUvMS76vahWTaXV5SbTVgWISIywvUcbqS8ziNOUlzFpvNWkOsXaJDjo1mUTUaSWCy6TJ2ZBEKxlC/szCwhSIPIuxUlRYEGFWsURcmcwia7ISImWsccuxkiTuxWQqWomVBKFREBRhVV7qdcnorzIwNvaC0qsMzB1/edVVZuqWS0jhBdclwu625Dxt1LIbLSFP0z+XVK/5UbLB5NRcQ7lwgUioEwQiUPBcaDS3Y0tGNE4VLRocS7a8hrMM5dZvmtJgNVQGh62QwsSs0awZuvWZ9gxmLWaf063D9GXxay7pSGq9pTHZqNZqjCSrJjOyayorGGI9pSkF0HZlXMDYyRycrCvDrZ5OTgR1WQkQNGUyjybJShCvHxMI+LWRU7L+8Fg1QX6P1cfESsc3yb1LZIrXk6hEpTdhuGyekIutbZwAbL/y1Tq5SiG+OryBv842D8PmzYy8lbSbJKlF8rCgZuyoI0KQBglIHZxOFIU0l6uQx4lIgUiTmMponIAWizSCrdDFGRjhSEMYi1+Jwi4iaaSYlDQQSoKSRfPISgMTIi5ZtojEdDPSagBktEkDCyMgOnnGgPQ0MIoClIVLH0O9YpQlDEtSAy0pTFmytFEfE6k8x9XGD1qwsiB59yBMvLIg17sPsUKWZVHlLJrOilo62ixtDRyWUdosc1EORezSNE7Ja2FyEF2NBy8tabh4kYmSYoKYpowtBLQQAiKZRwwsC8QZZeHMwWHy2UCBimgWKCqlLaxGrcozJylWA7suQllavxQ18DGClIUyylIDCSZOWbCYRDVwKkKVBXTKVZSMF600kS5dTcn4Z6XKWDTXImZplAxJC9NKwpbB88hbgafRqcNiuVjdv9nfVyik4s9ZGrU9JKpQS1Lzis0+1f4EUobAIXA7mIj8gqhkcdvx+IQDREIL247AVrZDyYyo7aKNBTKUzQnaLtxaFDPpDjHboQSlLEYmClkKySVjMRZIxFJMIQnrYWNKe53NWOSDbIh4Jdki0hVjk4UrBZU69rlFK0UWl6wYJS1YKaKUURoUq2T+VcYBRqhSADn3ClCkUgDXuV/wApViMD8JFaHgRWqHYJeoWD46ytrlKZCvidOOwitNQRYjyVU4DKVeB5VQ5AGEoCDt6IJyFCRDxCiJFpGiEJsiRAko35NUQRpYjFJgYSkKMjIrdmkm45NVLQzMil6ew/iEVSsLv+JXRrI/aRUmM6prGjNJW2PM7AphEs785FWQAhDnFE5AmmNcnDCnYKyyHCMARTkFFJTkGJ8myCkwrxwHiAQx3pHYn9AKE2CfkflJrUi+SZR3SCmSHKEUBXmP5ZLjAAe2wrkHij3BlXPctbLfTy+Ws3G9+W5Gnk/l37OkfXdM1NpXsCFp3iNE7CTGJWvznsjnjjAWWpz3DDYng2Uz6rwPN/oQLJ2T53281YZw+Q593sME/TnIJgp0Espl0EEaSKGTVCGH7qJj9A5AZ7Q9KB2i0Wm6iEcH6WSRTmLljoZulU6yxV06yEnLdJIpZ+QGdTpNcJ1RgRHqJELSHQRU6iTCle4ivFQnKexWHeHgtXoPYffqIAE88trNOkKgqfWew+vWURory3VIDAVij5VQHyKMoGDv+YKGHWVDFDsNF3HsGB2utSnCuNdGKa26lKbN8qUgNaAqSc6Aq4TJVu8eBxPSanvaIZuFE6ckh9WcggygOiWRgu4UJ7S+V4+HXa70jmkylyTy2lyESdC5PYvD58IM4JljN7oIgUnp9lApThfiPFhaEOq87RUI8FLI55URElAs90hBs8ywNWp5uXiYjcPb2WpYUlTFn7PEcntI1CuXpCGt3AFEnB1EJUvljsdnUSASWil3BDYvASUzQrmLNtoAKJvTyV241QMw6Q6Z3KEEXTJGJqpkCsllkjEWSCRTTCGP7GFjZIbOZjQbIBsikUm2iEPG2GSFTEGljn1ugUyRxf0xRknrY4ooZZQG5TGZf5VxgFHHFEDOvQIUxxTAde4XvDamGOzWGKDgpXGHYHfGWD46ytqNMZCvCeOOwuuLQRYjyVU4DKVnB5VQdwKEoCru6IKmGCRDRDGJFvHEEBuuiQm+uCUGGa2SmGTNcsQYM6CIKcqAIUa5eEFMA9n9MEbCKU+Kwuo6MQJQDlNAQTcM8xnfJ58Zxmg0MUzxeL0wQCRo4Y7EYYVRAuyMsTthIN+khDukFCOMULJCuEcy+2A4Hy5ufDYY4ABlcAcUdME0WaOC16u9caJwjn/JEsDF0VD3e0ILad8yNmLWNBZZ9pYUPteh5dOKt8y1eQMtjxG7ZaCxTtcSOZ1bRlor8z7TIXFLgKC/VXlEdduAuKytSgAJ24Yk5GqNRIxAEImMJkEnQuRsSxTxsiqRrGQblKwRyi1iG564g1XZaP3acERHUFC6tqnZVzCjWpvY8OgNCtYmNn0E57Vqk6w/GljO4uVpGWT3pmoqMOLZbamcqonSMtvrSHUCPD873VB8lSgJVZfMBarQkiloQXUeRIC2QBH3qRHh2rOmihtPncwqO1vCLM+pkgKKs2EL2E2VhtNkDYLVjam5oERsMIL+UKXSZF2D4/V0ModJUJVEKW5KYRO1UAXjMkJdeqNcdptxtiDPlONfspRLcTRUuZzQCvTyuav/tZxtx7fr7YI708vEw8aP08Z4pkPzlMGRAlxjkTVPSeErorR8WvOUubYiRctjNE8ZaCwUtERO85SR1iKhzyyHg/lyvVUjzxsZzmKHSioTgypJ5RFVUgPiUkkqAaSSGpKQSjISMYWVSGQss3QiRCW1RBGVpBLJKqlByRoFG4bX/xqH1e1wC56+w2nz7gy25uIKqyGIKyyVjVZYDUf07gAqrDY1e+RgFFYTG74zgQqric29O4kKq0nWFZacxSusMsiusNRUYKS1Kyw5df04qLfg0zbOd/NxttPnFeeNvBmKiKuinCJOJ8Dzs9MNRWaJklBiylygiCuZNBFnzkfEWwsgijcjAS7aaoq4aNPJrKKtJcwSbSopINoatoBoU2k40dYgWEWbmos6h71dcxkHn9hro2NiT6XSxF6D4xV7ModJ7JVEKWJPYRPFXgXjEnu9HavE3nfL9Zr7sfrL35LkXn08UO9NgIzg439Yqcmz/6oSlW0XfQ1GQJAAPKLsa0hchS7AQAq/JttU1AGZtPRrQm3FFZDKiL8m1lhckbl2MddAxNQcwiTJuR7Go+cQCkTQ9TQRRWenoktHjcpWSkJUgKgjqAKqDqESZV2PkzeKecVZzxRWZwgfKc96lvhIiwk0Ijn/6qYlWh+dMNJjIq2PvsJoz8q0Pt38HVs1nxVsTbhZsSHJ0Ehp1mxqsqKomnynpIIoLAz5BHjZ1ODEyyaVDdNVDVds5RjEBCgsAiqwegygkn/CqMPx/X4RwoHqtR4pKtggOuZniwga428WwenMDxYxBMZfKzJR8D9VJMDYf6cIY7KpTwowR34itOzPE/VY5t8mQvJ1/dqD+AUsQsQo2B7DKGGRbEyL9igxMYqQKWq0R3LKUZWF/2pyw2D/XjKWDXwi5m8kq8kWKdzAZGhhnU8Swy2QRw2rBNhXgBuU2Pd/SdtbCev/mG1m98O36/Xmp8dhRX5a7SZJ+po8LGixO+qIUKZBAnYPpxP1Ms3l8jM4ESmbaRKTCcEJaPVMI9i8BM7AiGgawmgoJAq7lqaRYnbaQChJahbN46oNTIiyZtki5trNSGsZkNHmaiyMgM7mGQNW28Aoym0WLn0M9apuljBsvA20pPhmydJGfUyD8xxXGz9oKc6C5N2DMEXOglzvPsQKc5bF7M1RGlaf0yhmi27gsIzaZqeOcihqnaZxGnYLk4Poajx4YUrDxatTlBST8DRlzMVbCAElzyMGzDzOCItxjjPsxy2sRh3LMydZWQO7LkdZWr8jNfAxqpSFMhpTAwkmTlmwmD81cCoalQV02lSUbFzf3y/xj/KyeToHK3cZELPjNZHg55DZ+KIcFvFLo2X4X5iWex4lg2Z9JqWNw1T0uKw0yoPJaRos5qgFwlpV708rgmn/z0lK+nIoUEMfiCLqeQoM6DqZQlTMU75LicjJpEqeEk0iQU6ilfEUZSvR5SxGDU9hxjK8TasfSzDMNm9n2+3n9UZ+Mw9bPk5bomesXThPmTHJrJBIYrlC8MhkJRsRyBVDRBqbWGjlILDYpIPGAgjhmiUggRUWUfxWECkjm1fwViRhqatQkSK3IgiNuZiwrfNSr0tazFaBsZEeE7BVYOJoL4nWKlP9jr+Usj/5vl1/lof2/Ua3x428Gb9Q6+7qhN2j+/iMBC6PbxS/Sp428poFr5IH3fU/zLbBe76ij6copzLWssHk3NwNvW63iNy0S3Xxo+PF8JQXL38lIkwqTzQxkayRAPK4RgkIY5kFlsQlT1gMa0xGGVyzJQlghVGXvhWVX/QqHG/Wq/u36sW8HcblenUfuaZ5kVzFdPLYlACN+HsTHBvxYRVdh4b0s8KjKOcKxKmZJQJe6U7JlMY1JsjvMaFn8eNbFOwUmaFdRSpJcRYYHq3Z5DaicHfznIrc3TzPEoXnQ6GicE8UEoWXwIhyESlkUXjJ95XTYjItCi+JtqJVTGJE4SXKWD6KWZwovIRZS8cmzaHuLtFBdSeTiOquRHCpOzkbUnclQ0jdWViYApJnMZaTCgui7iqWiLqTWWR1V0KkjDVudVeSxNWdTEWru5IgNAqC6q7KS70uGXVXBsbGXlDdlYG54y+v7spMXd0JKbz2ukTYtZecp41adu0l5Gky6pLqlVFKNpicmmuYuF8gEqbtAhGoiy40QV2kkCC6qEKJ6CKRBddFBU9cFylMVl1UsWXpIpkR0EUlVUAXyRycwinDjev/lERQtJQAQdEi82iipQTxihaBwKQpLiwpmkKiEjXFhOHSFHVupyle0JEv8jTFC6OmeBHVFC8yNIVAoWmKFzFNISRzmuKFT1MISaymeOHUFEIWryleeDXFC2GajGmKF0maQiJRNMWE4NQUUjaoKSaGoKbAWdgJP8dinv6LLJimKFhimkJi0TTFBJEy1gQ0xUSSoSkkKk5TTAShURDWFEVe6nXJaoopMDb2wppiCswdfyVNMWWav74ppUra4oVfW0h52ijm0RZsnq4tXkS1hZgNJqfmmibyLxK1BUsEa4sXSdpCJMG0RYES0xYCi0VbXHgytIXIZNcWBVuetpAYIW0xUYW0hcTBa4sp3K4tpERYW0wAYW0h8ejaYgLxawuWwKgtXqRqC55K0RZnDKe2KHM7bfHDYrX4YTaO3Fsw/T1PZDTHxI1GARtUGy1CrDZFuDTZ0RJ5KxGEhdMfLYO1AkCyWSHShptn50g6r0jaePtcnc53SZMWJmxPIDZFoxBQTp8C0YBihaAKGhYHHVukqHTm2gWjw+QLRRezMBCdpmMIrNzRMCBoCLYMUwNxcsqGYMoZuWGJQxFcZ1RgtQ6BkHQHgUUPgXClu4ikfggKjwPSOSQZ1EJ4rBBEAI+8Hk+kE+jCqOXwmyOMxspyHRJTmdVipVRbOiOsmVq+sG/C2DDxRMHFDBRCZ1FRPWGGk8Io7XKKos2zVBA1pKsIzpC3gsh4gUXg2E0WxAArLQIp7LYgQl1yEWh+26UzGbVXS5fkvwBORYR1YE4jRpK0auxhQUI8LNJE2OlQsP96WAS11zkw5BIkCkVynfOd1ZyUzCitc6KxHpKSOIF1jrJWHVIWq6vOYeb6ok7zyKlzdNRJiSSyiioQfAZKzMbEU8EQ800GFq7YYVmsFY/MAkmlkiXkkkQWRSEVECljjV8YFSQJnkikYvRQQRAaBVEZVOalXpec+ikCY2MvKnqKwNzxV9A6RSbwxSMx5f1scz+Mb4ZPw1KLGg+bLk+bevIESXTOcbghMU8bJR0miM9TBdA51e195GwwOTXXUkycITIqCJ4IVTlnmqjBkUkgcVOihHyNxDJ+sxvlUXo7jLPjNp6r2ySCisi4/5GZzNqnZEuzPSLj67u7xXwxrObUw3kroKHc0vkpIUqpiIyYJJFDv+tsY/ebvaSarXYzNeThvJU3hVNhZYbyFCE5ARVdRWDUb4k8qtYqQNw2iycQnu1zSQae7aMlyO+x/mwf4fg2DXeOzLFvApUs3S4YPtdW5faKjX64z8Mi7+k+52MZLFv0+T6XyKAf8T/h50Lgrn7tz/i5ZJqrTMdTfi5h9orP85yfS5yj3gs/6ecSHjdu/mf9lBBe5xZ/2k9JEbVu8ef98DT2+jL+xJ+KJmjeAs/8KTFyRp+IfEt97I/Mxeo394N/lDzkUk2+SnkF53/4j5woSLjA43/kTFHDiQ8AiuXqYm4K58xcgEBUdf6HEsmJ6tjqsnX+5xJdcgO+zvtkoio7N9lWeCQ+nEhgwqVd0uOJFBZQ22U9oEikkcTd9GCXztzFMi0qL/OxSAqVQ+Zd48FIMqWq8yYkxufF8jHBl/NoJpkEuH+Rji+WKkq/4qFQvfUL5vIaMPAoKjkTF4N5D6OSiQA1mPA4KoFBloPPeTsYzVTeefNPNYqJVoGY+tgtiUtTiLEHb9XJtUT8/qd3w2q73rz/OxE9/TFJJzYHBJ1iwRgRi214wAUhRKJibFlclT5CQcrGNt1UVyOptHZsY22VLpLLCMg22Fjv0sl2FdlixHwkRCVJSQLHYyYhDkRPEjwRR+ngootplctWX2NcgLKkuALeEuIS5SUBlDiueTUmQRV2mRAhKTQJmoTRF1ObVPYVrnVachLhGeM/pjuJ8GvcA1jxSeSb7adOwArINt5sIaFsbPQ0+0g9W5GSLYHTTGIcJoorMOAFTgsUr3F0OkxZtmQxb4lRAfKSwgoYTIQLVoo9W9grYnxGuUhxJhlGiFfXfASh3/VBTIwCI0CMHgxKx2QYARMzYhCbosUIKKcb02ks6qjlyvBHAKEkkTokj0kiGWqd9I/hy+OM+qyOf0jSSMXBQIV04oroozI0ULZrJKI2KhlcpZWWTuqiMtVUrGhptCYq42wlgpbH6KEy0FgW9Il2LVTGx5SQSiPpoAbDo4LUfEQDNRwRBWTkoQsYkcdWyug8gPZpeQLKR+URdU8DkjQeeTVPQxNWPCoZqXcaiuBoiWmdNjP5mqV1ThMaHacxjdOEZo/VrL5pctUvkMpJrKYpY8yKRs3URzezmpEzFS1TJjuVjJ4Ppydn48VCCRIvE2QqTL+URDH1otMA2qXFCSgXjQfWLTVTWLXoXEbN0vIlKRaVU9crDZlfragsjFZpAIxKRU3FdEoDEVMpKpOiURoYp0KRKSz6pOTJUCcKmaRNKhSPMumyKV3yz8VWOk2Of05VJ8UhTQLlRBrXKCVAuODVqAClUvIEChmNRNArJYGjbNCSJdVSRnsm8lq2qF3KcNeEvk/3KpgSJUPEqGS6jmmQ/FJGZcHVTMMUFzRGNqmQEdk8xY3OBiubli0sblQ2QN80UKljX0zlNGRJQkelFLROQ5QySlsUT5t/lXFA0j0NQM69wqJ+GoDr3C8UDdQwmNfxIBSKIioRnKJIzUdHWac0kvMhdVRShASSzmIkuQqHtYAqobKKKJnQopdKugzJpJPBqqlFCwsnjc2onWq+JPmkM7oUVMuaKqJUZlRHNZRRKaVyiWqqgXEJKpXAoqkaoAxZpfJByqoBC4krmciur0q2PImlUOoqq8LyC62Og9dabzcazdvN+gpy63xUh9/aI2cprgtGkk0Q2WDRdaEK13sij6q7LhzuWkrM16XXBcBfy4gEgPq6IASqmYYhJsAuQHkOTOZDNVgJFjVhMpFVhpVkWT7MQqgXazyhv3pTCI1irCJMcmMyIazHSrTsETNDkpV8qZ5MZlVVWcmVNcLbhVlFca0RQ9dmJUba3cYuz0qMq91xIIVWkoBLqtRsSJxdgkPuTKYwjMghgyZQGCTahSXBoylEdp5r0fhKugtabk0ncNq12oUxz6wpfEa5VgEm+TWR0KXYCspUy6aQBkRbRXwF1yaT23RbyZpj3GQ6QLqVSAHvJnPY1VuJlWffZEqDgCvxEhycwOXVcBfCbBMnsaIyboKL+riaplZyb4bZRwJk/89J8u1yKNC4HYgimm0KDFgKmUIUalO+qyaUk0l1NiWaqik5iZZkU5StVpGzGB02hRkrkjbNLr6m6JjtUkgkxVUheLyWko3IrIohYrBMLHSRJLDY6iSNBRBUNUvASiksooqqIFLGGq90qkjCpkmhIvVSRRAaBTGRVOelXpe0MqoCY2MvJoeqwNzxl9VAVabqfqQUVvhMEWbLo+Rpo5bZ50h5isSZUp3mRssGk1Nz8Un+BBGf10tEmIKZaGLeRSMBZEuNEjAsMgusVUqesEvRmIwCpWZLsiYKo65KKiq/H1E4GClShRtNiJKI6Y8KIOY8FB5FdFQgTrshEViUxsSS4TFEKkleFBgeY9Hk1pri7Wz1frEcX80e3i532xf/IOLbTZL0BXlYUGV01BGtQYMESlOcTtQdNJerHMGJSA1Ck5iKAZyA1iM0gm26jjMw2oSGME7hJQq7TqGRYmrFQChpFhbNo1wMTIh+YdkiKsbNSBc4IKOt9LEwArqGZwyoGwOjqHFYuPQx1Kt3WMKw6jHQktqHJUsb9TEdxHNcbfygNRELkncPwvQRC3K9+xCrlVgWVTGh6axuoqPN6snAYRmlzUoK5Xic4bOA47bRT0ARYky0T45ZmBxEV+PBS0oaLl5c4qTbYTRwHbeOnkOYzqMZYmrPQghoPh4xoPxwRlj/cZxhFWhhNWpBnjlJERrYdV3I0vrVoYGP0YgslFEpGkgwvciCxVSjgVPRjiygU0GiZONiiQ/Hp42jo7FFgdIgGToUppXUKIPn0aQCT6NMl7v7Hxarxf98SwFd/pilSesDooJ0Ygyp0SY8IpUAIlmHNiy+Ih6goBVok24rg4FURns2scZiE8jlVGcTbC0uyWSH3mwwgmIToRKVZo/jkpkIB6Qxe56QwLRzMUWxxmUsjiEuRFcSXBFRiXDJirIHShzX3Fqyp4oLSYSQVpE9TcLoC+pHIvsK1zqjHPvwjPEf1Ix9+DXuAbxa7PPNT/7SCXi92MTbxSKSjY2edpmoZmtSryHw6jyIw0RxBQZDMdQAJRRBKh2ozhqyoDSDqBBdRmBFRBnAhSuyji0uxyA+qxYjOLOEGMILqLCeMCDBECZOf/UgVvGFpIPKq4cJyi6ETdNcPZRXcKk04/r+fol8TJcNE7N3m9VPd3dI+G6zWh+2TE5HzolDeO45YJJ7DU6K1tMJRaHXIrlUHsVAS7xf3gkQv7xLlninAxol3i/vUiTeOTxBoEhEkMQ7s4SKXYlClHjndFcZKaXKEu8c6yvipFxF4p2DnQVcneyXeGeMHIknUiESr8CJSDyRwyLxCp4MiWfgkstQlstXlMpcBolXciVIPJELkngFUOK4FpV4BVWaxBMJRYlX0CSMvjaJV2Zf4VqXJV4RnjH+2yReEX6Ne4Aq8Yp8fWWgmqhKu3OcW9qJ2dho6ZZ2fDYo7c4EQWknc5gorsBgL3LOQHklDk9nk3ZnshxpJ1MZpF2JlSDtJC6ztJvY0qSdzOeUdiVnsrQTeXFpVxDGpZ3IpEi7AsQp7cR0m7QrYHKkncgGSrsCKijteBpV2p0hCGlnzlIl3SWMkHSuNOQzJ6ScNcsj4c7xmRJOIEQk3AUpIuEqhkbC7deXM/fG05+yBFx5OFS/nelC8q0KjmgPlUYWbxWHrzxVCWjpViXbij41kRFuVaSx3FIzOdlWhVrLLCLVIdoqhKBm04lEydaiuBSbzgAJtpYlpNesTEy5KDMZS0eACRFrHVNEq+lMslRrYdLGLLdQa4niOk2no2VaSxIeVUGR1uWmX8+MRGuD42M6KNDa4PxxnZdnbbauzpQ0XpxVUXZtpucio6BdmSm5mjCr0r26DGAwEKTnGwqRCiahCFHIQElWUQUVGUCECLIOKaLHVCZcjjVccTUGsFnFWMeYpcV0VkCKtXQBJabzcEKshbDqMD0ZlGEtSFCF6VyaCGuBvBpMITHpm4opRd5odKK6qXFc4qbPr7XNz8Ny9uXd58U4//CMQCj/nKRvukOCCqcijWicHiBQWmNUos7peVzlEUZCap2ewFSEYMm03umjbeUAls1onj7cWBJw6Xbd06PElA9IJmkfEsmjfkAWRP+QTBEF5GKjCyCAzVYSoWyADqLZAkoIZBO1EAmVOvZ59RBJFlZEICWpiUiilFEa00V0/lXGAVobkQA59wpMH5EA17lfsBqJZFBVEpLK6qQ+0qyUwHx0VDWrJSRf0Us9hVMxoSxGkqtw4IVTDxUvnRBCTDv1dDH1hJIB+olGCygojA3WUBRfWEWhjEYdRbMmKSmQWddSJKVfTYFcjJ4iYYyKCiTANBUJFFNVIJ+iq0gwp7JCiNi1Wz2IunoLymPXbxGB6gouOBE7B9RVXEieRQT2CBkyEKI8WD4M6bxpfj5cBLikJMLxadgs7r68Xs03Xx73F/w/hi8Q0HG/4bLfx8N+xvOGV6Rvf1Ao3v5wBU16OqhDlL79IU2VniGSpJREBuvSM1NYGkg0qjI9U7jLcSld16bneH8xLOUD6vQMECiGa4KYPj3j5AlUkQ5VqAVWVKKKPFaNWnBliVQDn170s3x+CSDzGXVqyZckVEU+WKkWYMnjY4ZWLehSxapIqqrVgippNLfr1ZLhSmOErlgLiKz7il2zFhDXurdAqrXgMD+3DiOB9OsZIyRgRQZ8NA5JWJ7BoGHPJAkiVuYx01yJxVe+nsFyy1ee0q5kz4R5UlamM2rZEi9JzEp8LjU7MabKWZkzoGdL3isIWpHbpmgL0hxJK7IBmrYACohakcKuaguoPFkrMhp0bQGXIGx5KkjZnmHMz8kDGSCNe4EwPy/PQIGeM+bn5mEMXt17xsoWvgIponwvWBHpqzEYipOw+OVZ7Or3DKXJXycdq4Ofazr4+TV08Pmgdh38PE8HXyByFJtIhurgC1NUd4g0mg6+UHgFgpiu6uBLvLtsF/N1HXwB8Jfsz8WS3aaDnxfF+1XOVZ8OLrGCOljmMergkitJB1v4VAHB87l1hMJn08EVX44OlvlQHVyCJY+PCTq4pMvUwTKppoNLqqTR3KyDK4YrjRGqDi4hsu4rZh1cQlzr3oLo4JLDsvZWSEb07yU2on9lBnz0jehfgQHXvxeSuP5VeMw0V2JxlbMXsNRiVqA069/nk55J0r8KnU3/Vng5+lfkG199mK1Ww1L5MmaBNc6nPWKj0JT+3Jz+PCXdrr4rlDz1rXD61XfFm6++ZW6T+i5JU9S3zKar7xLIr75lCrP6LqHS1LfMiKvvEi6uvgUqRH1fYCLqW2JA1PcEEVHfGgV6zkTUt8DgVN8XrGT1LZEC6nvCCqhvlcFQiEXVt8BiVt8XqDT1XdO16vthzXxc+z+kqe7LwWDFfeCKqe0pNKQJZRJFZU8MTkUjpzPqeko1Sg45jVPVU5xVJch5rJqeAs3aoE30qOgpPqqgFRpZPVcYPuWs5GOqueKIKWYTDyc3BB6r4tB4IJVc84QUssKjqOMKJGk88qviiiZBEStkjBquKIKjJaqC68zka5ZTv1VodJxGVW8Vmj1WC2q3ygWUrpQkqNwpxqFwlUx9dHMoWylTVbVTslvRavlwenK2pbyaQDKKKokKVa8TUVS5ajSQaq1xQopV5jHoxZIpQStqXGadWPOlaUSFE9GHFVlEGyosrC6sAMyaUElF9WAFEdWCCpOqAysYtwaUKGzCaeLJEU0imSx3ChSf1GmyKV3y62L88G6+GQb+VJk2SVUozWFNMqWgjmuVFiRcBCN0gGppuQJFDkIk6JeWxFFaIASSkmkRPJN+hEHUNC2EqwigKbzqpkXKkDgQoa5zCDS/2IGYcMVDsMVlj4NRKoxURk/BhDHCKohiDEshiBHQQwRc+hgaU0YEYZI8gmgFjUSQpY36FrVEcVxt/JB0EwGSdw+yKCgC5Hr3IUVLESygoNLTFVXVRjulFcRhGaWdIkvngJRWSxOSWxiTg+hqPNZCr4XLKvh0UosOaykzxBhGCCsyCjEsyxBGozbrOZMEGsbqUmkUc6pUg9hRvUbQRkUbxCcqNwLKJd8gEouGI8AyhBzECak5AjAk6XQyu65rGfPEHUCrK7wOzy/zSJ5G6/3Hy+9fvdwtbyie89+yRF51PNTgXQCLl/D180nBvP7uu9ev3r/T84a7u2E+mu4rRLZDG9YYEd+i88iisCbxVbc6A60G62xbdahnMjKwDjVWYHoqp//qWGu9ReU6hF8NETR9AJOo+DoYl9sDKCCp19GEbJ6ZiikQFSpjnYhQIeKup4oYO4BKVnUdTt4o5pZzHVPcygF8tI7rWOIjLSjg+uT8q5tRbl10wkgPSrYu+gqjPa/VunTdp2l5vEirw+wGDUiGRka7M9OSNVlW53stGUJhYcgnMJRSNU5CBaWxgQqs5gq6L4QJkV49VMR26VTjy83i/sO4GrYQznhTbp7JAeu2Dins2RC69RIpVA8GbblOPpuP6e+Hh0ecYDxufRWKYTMbdxvomppgpp1ymYzikwBMMp4A7euDV4CwhvOmmfmAau1AAo4VIOLkaodhtapANqhTO5SgRwXINIHaIXnNKcDybrh/GFaGAXB73KEfB93ZhsvmFE5cPcZ04WvVdajjG9VQNnAu2r9HrSWbFHkNk+LGVT5RijdALhuuEYBfVa5Rgt9Sprx2r+Z/HNarXxeb4ef14/BmP0njuLoNM6U9fXCLwe9fR1ipM1BRy2kg1WU7w+h3VgY6XsMzVHZTZKARBD2D43A4Bh5J3TNAHrMjEjmlPoOXYPgttKru5zHd7t/CBzcCeM5wV8DPK4gwlNfhyEy8aPNA4I12Eiy8eluBB73SeB1qOPC0Od0HCznfiuApk+82hiaFwHTlMUloX/BQ2fdBQ2ODh7r2vVBuefBcWP8DJpGbIQyGrzNiYbLfHXw9E5gJaaAwZJFuionPTXdlNmNxzoAm1ekwtaEdwxAn9GZMtGijRsCNdm0MvEALhwXl+jlBIlMzh4dL6eyYuCXLKXAirtPMAbRaFCSu7xKmczRdJNTEDozldYDtEJ482BuxsEqNEh7Q0zWxUBlaKDxkQj/Fwow0V3jYSKcFplSaDwwd1YkIU1g/T6InEWEwNyQYrLTuBE6utio4VHffQmIjGga//vrdcr3evJnx6wqKTTKbBO1hLe2Bktq3zr9Ldy73p0mcLYoOKipoITq9LdFx+QUXRMS3IjoSuxaCCIT2Q4fgEC4Qg9Ry6CA8goWhcLYZOqSEBgNGqLYWKDR3UwFjgtsJFFu4keBhFCSRzuiQRSAj2jYgGaMNA4xRbxVQcOljaKg9QBHmNAYwWr4lQJGljfqGNgDJcbXxQ1D/FEjePcig+ymQ692HZMVPsRByP4dG1vwdik/wYxyWUdsn9QEOROd3NBGRDzI5iK7GYyxhO7ik0hUgNaj6jjJB0oOEqJ4nEaNiHmIElDwBF/hyBUZl0vIUYIqQB1klFU+yeb54YWCRvn/B8ni+hmFkUloEIprzSxkooaNNQOMmNggwdnnJOQXp+8IGRgM2KiisYIsC45OaExSUpy2BkRgaEhRYQisC40SaEBRgpP2AkSHf96DI2K99ZJPZL03+SyE5bEq7pkNyfmUEJcHPeN8XSAAOc9umQ0tr2CC0aqumx3M3aQAew3dMOrCEr5owHRaqgfRu3CwexS+blNvktpCa49p6SAW4t4nU5ru7SCSLu43UYsU9PMKHNJJasogFRZikVlLL4rGKCIPYTGohXCYPoZDbSS2Gz+PRHO6GUguV0lGCGIGWEgEX6ClBVIamEkGX0FVyUIqCUqV0+UqMEm8sUZTxzhJEibSWCLz8UTXYXCIYs7pLEK/UXiLY8u4EpgYTRXK90URsMREoiXcmU5OJQLni3UlrMxE03j6TzqM1mloYb6cJIjGN5N5ek06CNZtanli3CaPyMF2PyFx8t3hptbfOamo5tZwpPSeMEW86UZDxrhNCCbWderxQ3wniMjaeCMSkzhNGK7tPis5nPXEaufnEEfm6TzYqtf0kwbn7TyCjqwFFAqd2oCB6zXMTmF7DDfHATSgCLNyFggjlNhSB5etDQSymRhSBltKJgkixVhSBGOtFQWxYM4pgi3WjLGyOyzTYj9Lp1IZUC+XuSIEshnPf25PSSRxNqRYusSsF8AJtqQ4w0JfSiUyNqRYtpTNF923q1tR6uRw27z7M6JvB9NesdlRzRLQRVWAyLaj/Ws6249v1dsHdPdrkww6P0w7wm0uyOFpQLVBE2SNMctuppfGpUYSDbjW1+Ta1iOQy7aU22KjvkGSupdRGW3UdnV0OQvPlegtFnzdMzAZbWC1JsHkFcYltKwLI1bCCSKBWFUEUalI5yBipqZIZ5SZGhrSkKLJIMwoik9tQBFLmKNuwvP7XOKxuh1vDaT6cdrnKmY63wgiyeBMMYqTbXwRPxt0JbHlR6df4fJg2FxGfcocEW1tEfP5dUmxnEQT2RpbOwLewWgB78wpKB0d4e8NKT18/DtDU4LRdYvLjbIfNj84bZmYrDboOwdmaw0hsHNegMAiHFilBNOh8YPOtZQu23TAupOFGgUVabQgZ3szq6eJtLIzQ2vigSLNaHhAx0FwgGANtBYiKaygQKNZWApRvcT/7nkGa+fE1MyikWBsDotMaGASWt3Wh85gkc0uWopcBRlEsd1AupUzbzUrUvhtW2/Xm/d8JiPOfkhRtdTjQz17oIkK0Dg44IJ1GVKE1h6tC1wlICVonm2pMPZHWn3WkrbLTMxnxWYca6zkq1a4da4SYcwSIJOHYoXhsI8CAqMaOJeIZzUx0Caow2apRhAnQiz1TwC0CTKJY7GDSxiyvwuuIwv4OoCPlXUcSHlUxbdfnpl/PtLDrguNjOqbquuD8cZ2VdF22+nsFWhqr4+oos4sDcpFR0GzhtFxFRtXpThOFMBgI0vPxYqSGidchGhmmnmqqmHdCiADp1CMFjJPOBOumlivsmhA2o2jqGZMsE8CqK6aOzu+XAB5GLnUQRrMEJGM6pwOJuRyASxE5HZDT4mgkFoVTM2X4G5VOkjcNjsfcEPm0tnm7FOct+z8n65vLIY0K50CaoXEmgITSWqaCdM7EEyqPZBJR60wEriJETpb1zhTtKwfkbEXzTOHOkqBN9+ueCSVH+ShkiPapkCLqR2Gx6J+KKUMBmdjkAkhg85VEGptBB9VsCUpIYYO0UAWVOvZF9VBFlqaIFEpRE1VEKaO0TRfV+VcZB2RtVAHk3Cts+qgCuM79QtVIFYN5sRdCoeqlCcGtmJR8dJR1qyYpH9RNE0VQOWksRpKrcNgLqQkqr5SSCG0aaqLLUVEamUFH1WgJSkpmM2upki9NTWmMTj1VsyYrKoUZ11QVZVxVKVyKrqpgnMpKIbBpqwooR10pfKC+qsCCCksi8misiS1TZYmUiM4qsCJKq+FgtNZGJNmss6XW6YhWp7VZ5yitc3yGOZCYMKF1ponVdBKHrLPO+b46ScpVZNY52FmfSMmayjpHeyuTOjsgss4gSR5L5II0VgEUslgiiUliFUQpDstAphRXLJmz0pLJLAKrJMvwVyIZpq8KpMyRLiyvCq48dyUyyuqq4MkYkY3iqky/xpWvaKsiPuWuYJRWRfxV7gy6sioI/MaKZ9CF1RnA76vEdHBE9dsqPh2VVWeGqKuSSWwc16BwlEpnpMQ6ieczaqozW5KlkrkskqoEy3BUEpldUU10eYZKJvQKqpI020+JxAY9VTAm2CmRSpNTBYrXTYn5RjVV4CSZKZEOFVMFVtRL8TwuLXUmS7VSAiMkpS5QISdVUbBK6tVPz2WUVz89zxdT54Pa3dSeN0lPXSBynIBIhkqqC1O0ehNpNFV1ofDWRmK6Kqwu8e7qRMzXtdUFwF+fNAQheXXBSfNXMh2osEqsoMWSeYwiq+RKclkWPrX44vnc1ZjCZ5NaFV+O15L5ULVVgiWPjwmCq6TLdFwyqaa5Sqqk0dwsuyqGK40RqvIqIbLuK2bxVUJc696C6K+SI2LABBJEgl0wIh5MZsBH44gNExhwIXYhiTsxhcdMcyUWV8F2AUut2ARKsyK7EKZZMoXOJsoqvBxXJvJ5dFnBmGnMFE6/NKt4872ZzG1SZyVpij2T2XSBVgL5HZpMYdZoJVSaSZMZcZlWwsV9mkDlVGoXvmSrJpGCYm1CC7q1mqXRaw+zzfhmPf9IsZz/liXVquOhPu0CGFJpdXTETOg8skCrSXy1oc5Aa7M621Zj6ZmMLKtDjfWMnsopsjrWWsFQuQ4xVkMEnRjAJOqwDsZlwgAKSIJ1NCH/ZaZiii2Fylh1IVSI8OqpIq4LoJI1V4eTN4q55VbHFPdaAB+ttDqW+EgLiqw+Of/q3v8Zzl+u5x87Bnsmo8y6uIS7CyjKuugr3GF4Pdal6w/G0vJ4CVaH2f0XkAyNxnbrpSUvkYnv09NW7nd2fXe3//OP63Fxt5jPsLnC+u5un7uqd/IzrBwIq0wCTS7W2V6viFBYGPIJDGVqjZNQn2psoD6suYLmEGFCpGEPFfGFOhWuCluyuCVE6KyCsKfMcoMALaAFO76AEQSIOBnYYVg9IJANKsAOJWj/ADJN/HVIXuensexW2L37sp37vmUSi2347zBmH+0gAHPeLjkZKwV8DpMgYPTlm4X8Huz/nq0xL8e0qswDbIrOnBAyxJLMhWnNiSgmBWQWWW9ODL7CW85WNOcU7ixG5XRNd07x3oK0zQ9ozwkmSX0qbJD+rKBCClShMWnQiipFhZrolAJcoHOW5BqdRYvWdBlqVKHD9GiFlTsahjVpxZanShVOWZdWTDkjt1Gb1gTXGRUQfVpxkAo1h0XRqhVG0t3MqFcrhCvd0XTNWlHYFyEiHLp+nSD8ClYhgO8CfhUrEWgl3ZTfFXUJ6UZNO8FoqjaDzaRvCzRZ4SaQoVp3YoqqXY3GynIdEoc0mLAStYHEaNS9E1+S8tXYLNq3hstQvzKdXf+WhHkKWKP0auCaNlsFK9QGHVxxJihhhUzTwhWOVw0rDEY9XCElKWKFENXEFVpUFUtMui6eUAhlnEIQuiOkqmSRU9XJBZRbKesEeIkUU8sNCaOXmQciFn/OlsvWRyKWpClqOeWhiBAVJpaDj0WESGSt7HwwIpSsSGXvoxGhbE0pux+OyKQHhHLW4xExMkgnhx+QiLGYZHLaIxI9bIpESHtIIshmEclpj0nE2DCNHH9QIkZjl8i5j0rEKGWF7H9YIphuGAyuMw4g+riksCzAdT2pkQrNuUsZVXHkYY0YgS6Klcc12lN1LRx4QCOWj47nfics5Gtl2yUdXeYjZBkF8CXauVRXIjHp3gnEtWA38ITMjiDqdt3PyCRJrsLhKOMzH5MJEBq1btaDMkEyi9RNe1QmxGZXuqkPywQZvUL3Ko/LxJgNOjfpgZkYlyZzI4/MxAiMKjfxoZkYHypyMx6bCRDtVsvZOP8AkUzbRu6AujguA+NzkONBfl2MH9a78Rfby13PP34+7pj12iP3ulRjrT6nFENy+2r3c1IZhpzakJfVvy6+Wyg4+02uIK0vh3WI6wN1lryeQJJEoUwHS+yJKyxzZCJVZk8kblUiE+hSe0LwKwOZAZDbE0RAG7QUMck9IeWJboUQld0VWlR4K0xW6V2xZYlvE6MuSwRGvz7RGI0SvGZMEuEKIyzDK7j0MTRDileEqWJcoVXleEWWNurbJXnNcbXxA5TlFU1kubVOpEv0CibvrmiX6RXI9e6MkFSvWPwLsBUaSLZPKCHhrnBY7iMh8S5xAKXvROFdNKUw2KX8hJS0MFsjtMr6AjBlebbCZ5D4E1mCyNeYHERX4/GJjgkuV3VIpHa5P1HmCX6N0Cj5a8Qk0S8zumR/yZkq/DXWgPSvma8g/hV2m/yvaHMaAAof0ASooAKNAIXE3gyowPIaAgqnoSlQASY0BiQyrDkwEVGSPI3EMnPyLziHOEzNhJZKaChkMUbvvdmNBpEWaTYUaJGGg85hKm3DjYeGh2k+/HOxVcat4xbZrYfiqNbOwwk5pfFQYmR4W40NazuUVDFjpvHITYeSw2eftHyl5VACON2KRqA1HEoEr1XpGQLthhIoqdug8kHNhgYs1GtQiUythoYspdNgJFQEkUjotEU6oaXN0BJmdBlUQqzJ0KBlj5jhFkPDl9dhUFnlBkPDlTXCG9sLLcW1RgykudCwRHoLKo/SWmhQ0u5+xsZCg3G1O6DeVmhI/F0FmUVvKpQg/p6CSmG4Y/g7CjKFVhaXDN6aWCYwthNKoKRugsJnaiZUeCm9BJkObSWUXNFOgk5k57kWjUNllGiJHkPmNDYRSsakHoLOZ2khtIAZHQSN0N5AqCnz+gc6qbd90BJndw9UckPzoGFN6B2odFrroEHydg5UDmPjoMFK6huolGjboMGLdg1kLl3Vlzh+U69RBO8cqQ5cYVUVeAXmNuAIhaX8ivnvjkbU38rjYi4bXUeCex8dM7EnqvDUx8gAhBYhnvRIGYAK0eLBx8sAFJAcjz5qBuDAFHn4sTMkSViUZz+CBqE06PK0x9EgXA5pnv5oGjsnJELSH1MDcdoFevojaxBOi0bPe3wNQuaV6dd5lA1CjCj1+GNtIBLzAHPNsQXX6+rjbhKpIMme8CgchAVT7RmPxUFoUOGuPCIniwjV7gmPz0FYbPecqH8PPFCnIYnVu3kP22mwUl182oN4WshEI5/wkJ6GLsfLhx/YQ1BdkcmtWa7xCB+V1qXpsx/nA1HaZX36o30ATq+yv8pjfiDemLi/6iN/EH6zvk9+/A/CiEn8jEcBITQulX+FxwIhrDahn/mIIJUO+C5AQxVY4Y7Q2GZd0T5D4gOGSLL4twIAzvi9+gpdkdCDiFq8YG8k/FAikiezeiaaJO8/DJuH9b7w+3l2u5gJDY1+y8x2CXN0S8+EeCnhxgmHFTXNFla9hcJR+v2ehY9vpnBcdmdm4RHaKhyQwwpZiKQGC4fkcUMyk7PVwgEm9FtMvGrTRQB1d15MhHD7RSAN92ACxIIUg4kdnsxGjLZkJOJoX8ZErDdnBNRrjeChNo3Am9OrMbHzDRuBM/sOZGjdSFTXHqGEdomAlX53NDROBKyr3yHlFopA5uuj4GxyM4UD83VUTFSOO4ivt4JTITqeY4s4eRuhn+/adMayn0NNqvxxboOs55gTjL2NF9X2EnDU3VuIbQKfp86x+DZyj8qXXkGmzze9ElDqC+xBs2+kXb17HJyYq+1p1+vxSe0Hgc3TgzBxGRoRAmZCN8JK7X9PHw87X/2dRdomAmWkd4JzjrvN6qe7Oyvffrf1YbdrcpnPxAPWFc88c7OCA03rWBjYxbYFC+rqXVipPGWtv4uB030aNou7L69X882Xx/2Y9o/hixXzeIjhcoiPh0Pk8Tatl3GzeKQQ9/+e1Va5HAttohygCuSvn08K+/V3371+9f6dnDPc3Q3z0TTlbDIdbZopPqKjZQ65BTMR+HSdnE23V6ZMm8qSs5jWyRRmVEFyGtcWmeKsiqfNc7Q8pvBgg0NhEdsZFYSreaGkQ62KiiLUmDDRMBJJoDEKJI0GaTHUNJGGgkIjtw8qjJzRx90aqFjijQCFi9b+FUNsZASVfp2Ye5Uyur6KDI7IoIqvIpNHZV6zV6l2qS7l8gp9CrULcyVRHdnsMlxK1NT3lOsV3Vo6mp2bbCj+JoyEQk9iAnX0xBOUzxoLopprmIhYlmnGl5vF/YdxNWxVjPGm3DQrH9bYFUpYWmtU66VW2B3E83KdeJYeU98PD3J5ekkej1umpw+b2bjbqNfIBDHtkMdibBE0YEkNAYXy9aHmVnGG82ZZuUDboQIINBkUEk4vV/FWjaxkgjq+QgjKd4VI09gVildaSwyCop6yHUJazVTeebtslhJNanmCSBHJIpcoaAsQl46VkkH5OiEEVWtrKXux+mY/RXjBQRz/milZiyNaVOsJ0ydcy0yndu3ynfK1RIkKM41JF7EljV+IaBy8lC3z7QJCyxUEbRnskAJasiRry2iPHOizneK2BEnQtyqXKnEbILfKVUlgodsQhbWukUxQICKZQ4voZKjobcmiulcl06Vvg5Q50oUEcMOVo4FVRl4GNzwZI7JBDLfp17jyBUncxKfcFQzCuIm/yp1BlscNgU8hywyySC4BfDpZTQdHVJ9altMRwVwyRDSzTmLjuAaFsTQskZLKQ5nPIKFLtgQVrXOhQroFi2ppjQyQ0zVSQFGrLCZR3WCl6GqdUJLWLZFHXWMEksCmKDwaGydRZDYH5FTaAJdDbHeQiXpbJZYld4PmU90qAyi8G5ig9lapJPndoHgUuJpvEOENToIOV+kQKd5gRdS4zKMI8pLDqcmBfOjT8SlzOd0szkugNH2uMKoSvYJyq3SZwiDUS5wErd4b6Uqu/3M23+0eCJbjH5KUenEw0KafuCIiuwwNWEONRNTXJYPL52jppLQuU012REujVXUZZ/MRWh4jqMtAo4HoE8vLdL4cZqtfqFlmdQbvt9o9ms5eu/wuE2PeW6WRlHeD4bHdQP44DhtqROzSzxu633lEqjepEZ9u5KHFj8hjM0A6DyDQW56AO1d5RG3egCSNsC3BbjveLFYv17vVLasmW5LjPjf7fQhD6SM4fTSDlWJ+3i9OAjcOGpJwz0AlI9sFDUXwXog1CdrM5LGSbg00odG7MNYQaEJT78T71GH8vN58NJ/1q+N+iWc9mhxP+nW9+Yim7V9kMJFtdJRR5h6Hmqnf5cydDTlTaWqUyc5+hp4Ppydn4yV6CRKvzTWqvZB4v/6WfmpvjbLfdFzfts/rteRhbZIyNtYh0WmA5kiLE+iLaDxwG6JmCncgdC6j2G75kpy2yqmr5IbMb5FVFkYgNwBGd6ymYtq4gYgZY5VJkcUNjNMTyxQWSVryZPhRhYx7LEWFYX0KBZIJTJ1dJrbLpmTnP559/XYpTLBOf09Vn+UxTQb0DBsXoRVC2CapXIAWrYgCtbvKIkjSisFRH6rZkjKtwj01m5ouCtQq3lW9EfkWnVpfFYRVTWCwyNaKJ8O56my6em2h/AYWoZFFbM/S+9gcElzTtkxxW2ulk8pZmc5T4wJ0sMLt6MImV6cDhG6LlXtv8Ovdjku2vKl8qAZjGCUblsNpVMMtZ5Ih1jkFUdwy5cwHLNq4I7jOOC9J5BYhaV5iUcotwjXmJnbB3FHpnjmH08h1NQ5ATrcsjKNO4FHUdQXiNNg6AXznd/pshQDS2hVHyG4DNFaW65BYhUuFlWVdVEZAgDdgjAdPoLHo8Qoqw5IDbLAs7+DCzlylM6rzhjDJoAOULpHe0ab6dJ0a1eotZ9Su62SiZG9xXK5dZ7Ao9xYpw7zrhJCAb9FCHl5hsuv4ii7PymucspyvoXyOHiLAy5WAse9JOHG/kWFOv7OZqe3PP91ptfb1L4cGpP0ZIMVGSlSgsj/zBK2MRKII+zOBsz6XkjVdf472VsVStirrz+Huepj/NVtE1V+uhICp5wmsov5Mk+XpRTJM0xdIMUuvsOiSviLxO3qRw6boC6IcQ29g08p0ls1bs8tsJj1fsqXYeZENlPMFVOpdIKbmS6ocM4/QWfRhT5hhD0VKh5YvKBOtvEipSPmCKOWeb1XyZf5VxnRNyBcAOTMPq44vAK4w+/DJ+JIpz8WLlDaqa1GAIr4gCXp4ngbQ8GeMgIUX89G7e8DB8/mwgj9ThA28zGIkuQqHR7CcoTLtikQIyvcJK+jeeRarej8jZZl3mcwk3ku0FO8usTm0+8SXaN1lRrd0L1nTnbvIbFHuBWWGcRe5VOFewLh9u0hg1e0FUJZtF/lg2V6AhV07T+RT7We2XNMuUOqi/YLk9+xaPlyCBC17xcFL9lfrhxuN57DNFXT7dFyHcz+CZ4n3AiXJMSp8sIIvyMIGRmFSZXzB4q7OFQZdyxcQ/gpZoQAEfYERqJM7DruqL6+ikK8XWezSvuDKM/caI6rva7iow9epEJHfMkVsvkZkVfo1W5bXt1Hq5b9E6TcCKqVR8zeUSa5fo4SFf42Xf8+Jqv+GL8v/g5w2bUmy5rhLjdfVDqh5U3sCGq/aGKjZ8uYf9hZBQ3K9+4beLKhREudD9rZBjXKtOZG3gdDQZXYRNF4H31V54KZCzRTuLIhcUHuhAAr1GDQS00wj1G0QSQwth4Inoe+gUnmYrkfkk08FXq5/UljhhkQFGO5KiFT21kQBl9efUBmNTYoGMqlToVC62hUVaWrPQqUNNC4a6it0LzR6Wwuj5s3pY2iEQDOjxgp0NDQWe1ujRsvrbWikhgZHjZjQ5RDZvK2OgjK73yHzIk2PEi7S+QBIbOVVuAfSEtGNkGfKY4KeXeExQdMxjc2PZ2mPCSoQEvSswgU1PAqikHhSWMRGR8HgkgxKttzgKMJ9xbySrjQ2inhnAd/l2xoa5VXhbmaIDLZGRsGT08TQ2JAGRg0VaV7oNFrjomXxNi00EkvDombKaFbY6GR9INH5RIJKZ2hQNHQJzQmNDmpM1Fi594ZIQ6LhymhGgHy4/iQZ4+pT4zQ3IGrOtOaDxik2HmqmnPmAreHQEFxnnJcbDTVC0rzE1mCoEa4xN/E0FhqqrKaCxmnkuhoH1EioWUJNBJFHbSAUIO7mgUYA3/ndTQORAGwYFBzBZoFKY2W5Dold2RRYebJGYYQaAxVYqCkg0tgaAgVUTjNAZTM0Ahq4hCaAQmduAFSEafJfpXSK/4Y2Wfpr1Ljwrznjsl8jU0R/jeOU/BqDTfDXSDlyXyMExX6NFpT6IpNH6Bd0mTJf5tREfgnllfgAAV6uhOR9S0KK++df8yTPv84V9qfj2WT9868zRP05Oq4fJR5E0J9JIgJGYpDE/DnbU4RLmaKQP4e6il4pVRbx51hfoVvnmgT85Sz3ync+2yTezxwp0l1kAoR7AROQ7QqFItorBqdkFwkMgr1gSZDrBiqxvGapXIW2TIUL9ZIqLtNFKkSkFzh5Y3hAoJc8CfIc4YL1Xs8WVnsin1WYF3xZslzkk0R5wRK/P5sEeZmcPy6LYryITpgfmIR4EZ09R3CI8JImSYKLfAaeq+Qj4rtgiEhvnkMT3mcAr+wWk6E7sVdy88mY4D7nx+S2TGFhyCcwK4szTpqskNgQkT0BRSQ2T2ES2GeYFHktM+HiuoSKS2uJyiqsJ7IsWS3T+UR1SZkrqUVaWFAXfGE5LRLJYrrA8ElpMdskpAuUFBktkmEiukCKSWiexSGgz1SJ8lngU8TzBcYpnbVkbPofkc0VASWa3z3jRfO7Z7mi+Xw8k2jeA8ZF8yU6rNxEHkA0X0gCkkJkEETzJdtRyIqZkmi+hHoKSTFVFM2XWFcR2eRaRPN0ljtFs5BtEc0XjgzRLDPpormE8YtmjUIWzTWDTzTLBLhoLlniotlCJZW3PJWn2FWoYNFcUYVFs0wFiOYSJ28M94vmiicumiEuVJ8RbFF9JvMZRXPJlySaZT5BNJcs8fuzRTRXyfnjsiSay+iE+YFFNJfR2XMEu2iuaHJEs8xn4LlKPiCaS4aAaBY4FNF8AXCKZjkZuhM7RbOQDInmS35INCsUFoZ8AquauOBkiQmRDRDNBVBANAsUFtF8gckQzQoTLJorqLBoFqmMorkgSxLNCp1LNFeUqaJZpkVFc8kXFc0ykSiaSwyXaJazLaK5RMkQzTIZJJpLpJBoFljsovlClSeaJT5ZNE8wPtGsJmPT/4BorglI0SysaH6XvKL5fDybaE5Z0XyJjiu34IrmC0lEUjhXNF+yPYWsd0XzJdRVSLpXNF9ifUWkf0XzdJZ7RXPOiuZ3xXqg7LPeLppTVjRrFIpoTljRLBMYRHPqimYLlVjepq5oVqhw0Zy6olmmQkRzzopmhcMgmnNXNENcsD7LX9Es81lFc/6KZplPEs2xFc1KLjo4X2FcFkVzcEWznCyL5uiKZiXbKJrzVzTLfAaeq+QjojlnRbPAoYnm4IpmORm6E3tFc3BF8yU/JppDK5orhnwCs5rIXtEssiGiOWVFs0BhEs2ZK5oVJlw0p65oFqmsojl9RbNC5xPNV1vRLNPCojlxRbNMJIvm6IpmOdskmpNXNMtkmGjOWtEssDhEc/6KZolPEc3BFc1qMjb9j4hmYUXzr7Nx2Hw7jAMjh6u/Jwnn/pigdK5hI+KZQAhoOJBLFNAEkUtggCykiCYYTMUumE0LaSLcVnSC6YyYJuKNhSebb5fEBExMFKNskiymoTzCGKVBlC1NFdG2Pjq6YETobCUkTAcoXIYuoHFROlHl0li5o6FXTdJsYT2JcpKKkmbKGbkxVckQXGdUoJUljZB0B8HUJY1wpbsIq+doCkLPOXJZJUeEmrUcSgCPtGY9BxEoio7gcGo6mMbKch0SvMgjsOJlHsSISTOCLybOYDZAnjFwAYEG0sESjSQMizSY0ijTGNokoYZS61KN5vSLNZSMkWs0jlGwoQyYZKORYqINJVRkG43mFG4Qk0W6EXQZ4g3jlBQYBebRYCzJn/58AflmsXm72yzuFsOmG333Y8DmbjYftn8gNhOt2LOvn/+xvtBX7x6H4iQBjn280Ffb0370DI7i5zGqqxpE6C5uf/zbzeCEeDzsmYWyb839dHdngtjvsz7skxO/sqevnOHM+f5u2OxL629n40xhKbbEz/qbZukfduin1lWAzAtioOYfZqvVsHy+L6O0k7BDO++8HS0NARvg7Xq9+elx0M6Ojm2/3/q43zWw7rDxq8OyjF8AxmL1w7qaBoAYi9XD2jQFsGEt1/OPrjNqv+M1z6YHfajtmNBBFoxfevKXV3w/lpXGsUCZlI4N7PHh+Z+sTKd9Mj6ozeyz4zbwdDP7fHvc7Rrvybni/nH3cFNMYEG2896r895XQfRc9P0FHwPYaTNWksCwaE9F4iYYENxhI3xaMVts/tdutlyM6sxiOvDT2WLzfy476e/7kTs2rynSI1MaEWWqbauWik5U9HosjRUY7Ni0+V6dLhRIx10M3QsYBp27FDCmaYsYjtyBi2D45iuGIneTIhS+kcih68/6KF2mnrYPxh7NwO03oyH6tM9szD/ZPg2bLTBBLWCmPeIo1UD89vtTLfjz/la4pd+gdiN8ID4pZ/yoT6c9mM+8I5aj2UFPjO9GPBfC42wzexhG5oynAcp97PHcZ7t9XK+26vtw3MpQva9v6Vscfcynp+31l3XC5YbLYbud3VtezdNpl2j4cVr0ihuxmfzjXnNx4JYQms/1uESCATj+0XCNzpaLmw03R62O97Tcln0ZJzoubrcZZ4vVcaPt94xKbWKP+xxv/9vFLd+sVuPFWUedSs42HGFsLUnFdfWjI1AY8/pAbaiTA48tilfL9e72NO0Hgo87zfc7bS87OQHuN+vdI5B53i4SA36Qh21jn+OH3c23+In6YXcTP1c/Dl/eLNgJQBn3cfiyPG7pjNobLfAc3W8aO0MfZlv+DlxGXTb0Bq0/LVb3SNB5Q2fQXuF+u9g0zU4+b7/9bbG9M3a7XNwOb9fbBRh72P5x2t4ZK02W60BqkqxFkTdWwUnUm5iMBNvSIo65lxFymdewcrG7cY1nHjcOBUrig8qktIcnds13DMnYtdInBGM3i/sP42rYbt8MnxiLTcZf9lue9gthYDO4yu3g8zgl+sNiefum/LajGr3fY9l+49ETvV6u5XG9tllL4fsjlsj3w8PjsJmNu43h/d7vOFY7hkCgWaxqztzB6s27j8Zu4kr4er3hW2hk9nq9UVQ6Fj0sh/m4Wcxf7TaHHVGA837zy34pGIvxy093387wcbbYcX13OwsPuKIvpQB0W4oF6/P9MhWc9cuR6GS8DDZNybX4h8Ut18qgsy87hIKXs/nHw/IoOHm/x+cZNItWovf3R9s99bBLyu1U7tST2WSL3hH9sP40HBejGS6t/U63005RAK2IaaKhUkYOXQ03u+Xi/872hcLru7vFfDGs5vj5Xu4+lLuHoPZVk+0s2O+RchawrRkqVW7MgIFsW4ZMlJsyWCReTZbRxppSQdg/bQuPPm0dihwdc8fEaSNSS2ttJ0/sejnywp6IvWwfij3cid4Ms4/mEfWw53KYfcwaVj8P+7sTnn/e3Bra6IzXm816o3R/qm1Sej/9EdXOTw3q6vsQqUDXBwpWez5ENtbx4eKbz1H5CFM/PdsHF/vMzB9X+JPyfEjK5/Pyzetvbj8Nm3GxHR6Y2rDdxiAOb283w5aUkeRBn0470C+ow+WW0ZLDJZ0pFDlw3PabI/js+L1MNHk7q3aLQrxezTdfHpl7BYcwFDvFAA5LSL/bLIbV7fIL126iMQ673p12FbtPKMxm9vmb20/cmk+aYjP7PLv91C34dMVvtwtD8HHrWORW/rYDnXzayfuam6Hk3Xy2+ulxP73lrvliC8Mwcng+CHjEp5et2VdTYnK2breZcZN7KrTYPhL7MJuj79zT07ahOG75OpnXLVuHAttTRD1Ls7+LQxxS7dw0oN7v2lDR/Hds7ADSd2mobPI7NPZY6UsqVCz55RR7rKi2qFzdbGHB3BJXKlPszOFx7FWpf5nEGSjcsMEvi9iDhW9lULHUtzHsofq3Lqhs4dsWDgTLWZxxBvPfouAShWeqsJHVUL9crG7fL5aj9KXjbiPDwr/lmi4p6WM+PW/PvKSOVor9dv2ZHvuE6NvjPhnxv5AtJClcaCPB0WvuPkPnyrcZNPRxtjN9yuftg7H7b3ILdpcJ33+LW7O7EgJ5+WjzJWK7nFkTd2B97kShK4s/tDe6n0VVOyaAqFM5HsX1pWkLnDjNY7nMX5i2IIlTQBZJnwgaEOQ2Kw8B9FpNGOKslKcwfzHaAsXOWFke0xNurCjGT8j2BWkzDDvTlYG6+W4W1CNyq+m/HA3faoITcZbA+uVoCxAwSWe5nF+MNuHZL/jrXezC5F6kMXxBWsGhZy4AlnEhMjRfCXwvuWXXlqzSop0iqXbRrtfgV6JpAN8XokEoaUkniWP+MjQKIn21gCZRv1wARvOrj8hcZfURGIrdO6r1L/Btw/+tZDLZ/p1kEEVYGEKCWL+PzGNU495aVh1rh+TYP5uOlQ3NAZ/uN5Ytw1otfPfHYPQCFSd5BT3ske0Nt1mPclNYj9oO45v16v4tnLgdxuV6dZ8RzH23g8qU7bEeJzz3rYvTnveGxmFnp/J8Nzqsub40F7LOtyD9IXX/sc4RDkS0UzVAQKJkIFjsegHCEMUCgWF+8BmGIVf1BIejnodA2EqeYNBGj1C1zuQZ6nQcgK3QOQhbbQ6BSCUxgWEuhiEIoAwmWLwFMIZkuSqU3hUcyNSRTKKlsOUQ2luPCJFYxq5jBew6Xj2uU+pGDUSsGNfBWlELlwZV9FlVagj7vYQmRf5GghojF2LraAmmxUvF1zpWdhHR1VW5W96IFVfxd/zalH5JQTq4+ksK1Usr0QUQ9mcTVBLxZxPsKOPLy5e+UYbxptwlFP6K+7I0mSt/WdoSuf+ytC12PO6REy1810Ym0L5wA4K8vrsb5vSwQsUP5839oVL52kWq9SsaSA9edJ5QwdJx7Yil1bD1JjlzCuKY9plFw85hLHfsCdszHDfm308kUB2Y+lhsYEop4ql8ZxUPIu0HAVY5kTj7PeSpjiEaGLhoAnTgQlTGsKSfLkCmn7eORUr2hEw16xMM5H4zGCjOW4deu6hsqFS7s8FAZGlDkTisDYbCVhgUhW3tBQ5AixyOwGByDAisymExbC4HQzn+ugrMcdk8dF1IBolKNSskEINpU5MIUn8aiwOUFZXsdVYglGlUUKwVHskYIy7T4q1YiG7CKXMkqqv6cL4ZJvjEMigfnOb5ntPVpulVZ/zpXGQmPG+KesEu3CcGVRTRDDYQdjWoxvParslWvJ0aJIu7Jsxh7lQASd018WZ3R4WXI9OrYbFcrO7f7C9RyW5R26XLPDYk9POo5EsMyj6Z1P1bqTZURQZKjJwUTIRjZaHI1Q/f2UicTNSxOql4DTThtoMRUvegRFBeRop4hJTMghJkJY9ESctUIHI4V3jwcV3B4UZ4RXoym6bMSqVjm6eo3GsyylCZqZWimUDwwI1K00Q4VaaKfD6pakWU5KqMR0rWbDTDQG6TsImgrJwV6XpJm4kkyFuZyipxjWCszBWpeqmbiCTJXpHKLH2NYKL8FcnsEtiIxslgkeqagwUrh1UiXBJ7kDhZrGOZpLERjZfHIhchkROhBLksUlklsxWLls0y0oD7GyOOLqNFMqeUtkK6Rq2rjli8vFaZDBJbh2ILCowvT24zh41VEAHZzfIEp+k+Gc7R+K1KXJaLTOF5blCm83AuqY6jSXKdgzJLdhyHle0cSy/dc0BEGc/B2KU8DiTIeQ7HKulFmGrkvfy0425Jv0HlBvh4C1wn3YGlS6R6cRUzdzVwM6g+VnzwGBQ27B+XDKadtw3EbXfzOXfz6AOnrQORu+1w+91subyZ0T+pROTud7mbdrGF1+foapzNVdPYbZUzO6APq35VkIB2yzEGwenFYDDRnTBMdm0C44h6gsGxmwkYR35GEQcEPKHIgCB6EY7ArkRgINaGMCw2EWLCMH0qRv1hA2HNhwRjkx4GoE/ss+B5nss+0RNWeqQFF68+1QKPl8QKk252KjAM4C8YJq+6wNGsY8q1xhPBVQgkFk0hoVBzEBUo0Ut0R7QriYraZyMICn31HRSM1AhduLeMRoDECrpHsRfPCIT2U2sECPRDa1C4+ONiRLL+02JQrFyi97GO6hzBkArzHsJckzMI1TCz24yzxUpcJ1ZvYijJuccqU0dUHqrccnJNzmF8/a9xWN0Ot9+v7shffCbD74dxOO23OO4XwuCeb0xmi083BgPZZxuTifKTjcFIdD0kBWD5frMBB1r1yPHA33KGgcTnPjMc+lOf+XjiugYvhnIz/Po+3o5efZgtpFfYHft0G5uf9hNfZcXPLmxY7x6FeRKHcdhPeTy9jEG84Zoz6rbKmbnRh9WdUQ/NjeXyw7U5AOTR2gYIVVxxGD5xBYNhVwKxEAm+EKL2jCMw2zMYR7RnDI7dnsE4ij1jgBB7hiOI9owjsNszGIi1ZwyLzZ6ZMEyfitGe2UBYeybB2OwZDCTqK4YHnUAE9RWTbtZXMAygrxgmr77C0awX9bUuaEFfCSQWfSWhUNMhFShRX3VHtOurilqZCjG2pKcAnteNBev6igh36isESNRXPYpdX0EQ0lO6KQr1Gd1QLP+EbiJTeT43FIjcCyzP5oZC1R+nJ5Kxn6aH4mVN10c7NB2CIWm6HsKs6RiEcjg9/so5V8VPf8UH0uMvm766jA7AcU+/hjov96E/3ALXPo63qVoRC4QtmUGqi1q2w5M5SBEARCLys7l69Hy53t2ewl+v9j8CDb3iw24nguGymxuiukOR9/0OoLo/8SZGDz/eXrhbY5t73Fpc9qVHnn7verFeff9PJHTafvEpJfYfA3QJTTt8HCIX0nQc7otrfLL4VDA9+sPu5lthutHmftjdkNMNWyj90+9tVijiYTZHMo6buUO4CruLEX8BVg9aMcVzm9PVy7YY7hfR2xjxt9D1GOG+3yZRN301rL/Dv1lsx5+H7eN6Rbdz+q2sun6/r+HIp3FyedxLem0VOusE7zazzXD78/CwHs0o5703h739SP3bzpep5d9TqtTugOD8Jloa9rng4mckXioE+2BwYA6UBn0mXRlYQ9UBQasDgMDq7Fxs5+tPw+bLT4dbKH2GNttYBwTmU6OOCnxyLbBvriaEy+cqGH83jPMP37z9Hg8/7DF7FO4mYDR3vydTxbs+GLidz1Yv37zGQ/c73Czjb/K4eBjWO/r6JIOnHczB5UXz9532YOR6i5RhnTik2T424N4mKIXia4BiQFLfkWIx9xwxjLvZh82w+jAsyDOOAqn2oE85LPrD7mFxuxjhE6PYPhIrdVipWHN3FcOQO6sUCNBVBaOljiqZbO6mYiBcJ5ViMHVR8Xj43bd1Tw0AXOeUhTB1TTEQoWVJYVjblRiE3qqkWJxtShDJcpVc4wrhW5McgaEtiSGM8pe8KQ7kgahseDspEd+BvAqzPpprFhKsNRsCZwtSBZHqlwbB3HpUw7V7fhEO3e7FMP0WW8SBd1cxELhUikT0KvEX9E2gvc+nxgulfRNu7e9R0fXQsD897hbDRlq33G+FDxb3w/h+trkfpFOIPPp+Xfx42FM7n7qXwK+K/mY3kl1MjmE7jLPjLgnhr+/uFvPFsJozFy6LMJQ7JoCYP4pt6ofww2y1m1nzH847ZQCwM2Y+Xuog4eHCs1a5cO3noYzhzCgjZPMWUYymhxnVjhAbGhYW7Ma1/uF2M639buAHDEz1xOkRy2CfKhmQAG/Dgnn1jQFPtjgsmUPmGKBkw8FCOUSHAWo5m3/8dTZyhR1Ltd/v82m/hFNccR88hkOBGLB4E8ISGYWIEUa5yYX1iBWHtyQyklGWGLDW/DdwBai18j1cE8LjsJkPq3F2b6WodkwAEf0RS2HXSAYkxCaxZG6pZAF0nD1XHIEk0yTymISTDMRMvBCyTBFEHDQyyQlrIYrHbYcwLFkSUUAOV4ShyMqIQgHMERaNzllKjWSZrihL5dUpQbVWHisCxMjVcLNbLv7v4YunaMlfQpT7myp/5yMqaQr5V6HQUNXlUdGY0sMAFLNHxXsEHwYjej4Kxa77WJDyrvCP4cvj7Ja/I5R/T7kbdAc03wkqZPddoOdw3gEQHGn070HMIz+CINZpPQNdnllDxUuuD7VfbgiEcKn1CNbLjAEoL7E3w+yj4rqaTVIuNOqY6iLPltUrkchwnz4CkSRxRNKYlREIIskiEsSsiUAQ8YonSexOBkThpl4khcnDGABIA8MS4O7FgsBZFx7D5FtAFMEukCBWrwBi6EaBpHG6BBTKdMVc5WrhzQHLYHAGIMSh5tpvKz2Tj+Q57LkcZh/VR/PxKN39U35L8qanzeHMk9MC1j01bRmcE1MdRZqWthDmSakeL84O23z73FAHEGaGbbx1XqiH4xdYgWG8tsRp6Xr+UVrpUf7dtMZjvyP3FfHuoPulHftph/i4wwpVmO1giact/VHru7v9Zj+ux8XdYs4+jKxPXt/d7cNX9Y4BkJWTY5WKsVvhb/5l22jcr4vxw3o3/rJazsb5B0v45+Oeu8ueJpT2EtIqu3oT2/qF/c7fcr8tSR35sHxh/xr735ZsX1ps9QIZrhaXWKzyjD8yGnnAHxqv1rYkgK+2xZDE2paiIWtbR7BYy1LB9loWA5FrWYpEF1hgNFu7Uqm22hUHoGtXjsBQuxoQ2NqVxbDVrhiKVLtSIObaFcMAaleKxlu7glCmK+QqQ5VQu3IMwnNv+dDuNiznJhaI9eHsBeIEq9z/mIqgyQee6gZE6jVpG+usSVUUsSZtIOw1qR6/Xm/kG02Zv15vgHuMvy/TBoI3tUDV3QQ6qm4VQKq6m3hz1U2Fl0PFD8OoLjxut0kZNsiDqjPmDtc7Z6XjfZNWFEqatdI85pYMiiJ/KZuGAb6WjcZLK27ocHXFDRotzeDpaPMUHkURRzqaxd6QQmG4WT3NYZrWWxDIeT3PgE/sTRDczF4AMU3tURhhbk+jWCf3KIg+u6d5nNN7GMt29VznyuFn+DyFoT2FYijLyWgWZDmZANDPJJT3Iq/saI9nrjtKXncV0FE4ywAARqoDOgxzIQAA6DdtywpZIBA6o41rI22x7+azpTl7e9rJDSAWJF2yvSIBEISSpAOw1iR0fDWUHOZbWlXSbpQzrJBH1euSjthdmNAAzsoExRJLE5rIXpugMOIUnYaxz9FhmPX4cjeONpr1eHPeJ3i+yE+YYPKBJ03gAGKRwuTbqxQUhy1TaBJbnWKBsHwexkrFhMGWKgKKrVbBcfiflGZplF+UhsOlSonONpdKKApQK9FE3mIJBjNexle6hIV6ieewFEwCCDHL0GgSS5b2gPaapUTmAMRfcSYY9B9xRmKBWqmL9hZLAI5YLXUg9nIJQNB+v7nHgH6+GYmWK4gu11FCABBSDdEhmIsIGqC8vt8ud/fSer7y7/j1Pa7v7+masDve08u29CdZAXJx/ENxiDzlcThwIPmhMXn8JJeJaz8jpc5rNkkZialjmgfjlt1b8ZEwvnoPRdpt9ju85b71ShMdd5K/+woC3HJr+Mhkee0eGilUuHSqtb4FQaTqlgQx17YgiFjZkST2ug5E4ao6ksJU0xkAyIqOJcDrOQsCV83xGKZaDkTZP8x9uZ6RsxaSpNghdJEKVRyZa63hQAy9giNpnPUbCmW6VOVFMYZIujZiMw11GgrxZTX/ZZy/XxiujP0+u3E+LoRfMwLj98fAT4Hz1qHIz4u7xc/MLymRqfsdxJ9U4oO7yZj8kecVw83hfLOvYEXaMjjrUR1FqkZbCHMtqscPy2E+bhbzV8cpHEJx3mV+2UU4s6Dwxfjlp7tvhWkfkb4Yv6zvbrXJn+/RLm0mMLH119xtmL3i1gGEeruNt1bbQPh6yT0lrgu/bGp4q6txajNs9/dZrXDsN8sZuZjjqk1CittdNHIQzsIRRxMLKY7KXkzhQGJBxQHZiyocSO7ZsUhA184CIVZ3LIO9wsOR2CqPo7FVejYQ22djrPiMKGzVJ+LYKj8LEt/HE4iUTp4BQKoCuXxzJYjjANUgR+WtCA1w5kv8ape3UC1KLJaKUYQhpwg6U2JJ0x/SXtbU4K4eH8mhd/mwaKCqIuK9lRWEJFZXBIy9woIwtH4fhQJ1/LB4uf4gsh01CAQi1SEEhrkW4SDK6//nfcvg3efFOP8gtQCJzfCR4H4YTwX13k19s9o/9G4zcp6Ki9o/7+NUZO/l0f7f94cR1RX16sztShZI6VpawvnmJZ+u9DCt8eR5KKfzHU05nDkBlTKV3jLlhiQc2nxjYl6Qt36V0HwlrBGQV2EimqLDbBBSKS1RmKtpG5ZUUEtY5prahiVWtBKXvai1gXF1rcRkKm3tOGR1q/HgBa4DiKtxVShTmWsDY92wBCV7YhuAUOlKCNZi1wal17sSm7PkNSJ6hgG5JWoHoOtKjcBQ7tqQBAMvMWk2XoXgZj3QO5RXfNNHDU1zgnUwQ+QshWEwqRpmkMwFMQwDdB4ZJrQBaUaR+pAKi9qOhGGgOw/cnIRjRUfARNs1AYwjmAIGxioLcBRs9DS0MaXoesx8WI+CqCz/njRSNgd0DJIFcmB8bDncQ6OOI4+KLYhjQNQRlIuvZfBcdzqEeMm1CParjQQoz/Z382E1vFlsx5+H7eN6tSXPjG4j/LzfnnfFj/v0sM/yuA99LffUzKsbN4tHSThWGxhe1bC6Pe317jS/xo7+dL/n/PQv057Yx1m/GgHth91yXDwuB9srP7A9nHadT7umwo0vxVYJSTUyzZIMnFfr5Zq88dMk89PmV4B4Pzw8GkHG4y5XghEe9aAwUQ99yEB7fXc3zOmRhAQaztsnYggOnYCg7HkOAnnL4AjwWwYH0I2qikVvt0mZKZEHNc+WOnwOZLnjT/6e4rh1MoI+WPYgzsEyo4tAE/n6BzDUftThfkidAdrvYjK+Jhhk8KSZ3INn5DteNE//Ja8UCKHDwnBYeysoyv1msHCcN8+FkFo7NIe5qYOiiO0cmsXeyEFhuBYOzXGVS5lt2/AMeMPGBMG1agQQU5MGhXncr/Tgp199Z+a8fS6G0KShOaztGRiEXlfEQAy4vUAB9M4QzeLsCcFYtlHkOiMI3xHiKQy9IAGjnyorKHkqsT2ec24cWOvYE3ino4rNlMr22mGaK3YgGpritRT+2V3Q7BI4LrELwEhet8Mwa10AgO3kdOl9DycYLQrlLt7ukwEEQSd3AFabTMdXo92hu/JyPb5ar+4W9yRFvQk+6v3X4SCrGT0lI476tNyD0cgNLzvgbodffn4DB++3328ZjL0dxtliOdy+3mzWG3qwpdLPuw3n3UIQw2p2sxxevnkN5x/3uBFWrJqiXy02891ifLkZZh+ZC5unmB93vrnsnAF0GTu/X43Dcrm4Z/W/AHY5yKI+SALgd7Pl8mZG/96dgHQ37ZYA8fMwMlMUnmBz2icUv1zf3xvOk8vm0VD2+4VcrPzNQjD4Yfavwzv9zbifXIz4KPEw+9fh7Z5NO4ZAVusbelk7mX7eOhR54P9+tRgXs+XhRwh/wF/+Yd/Fcd+D6XoIvwOHQ/4w+5cL5WH2rySM7Xy22n/nYb2jpyEUwn6f8bJPLH6YbxhHQCafNw+FjuuPjMqjMs9bWyPLmc4/Z/Pd7kHqr9Zb4POc+XKYrX4hO4HEIZ8eNt89si+nAeW/OvOSryqp3Pth1L5eD0d/u9uON4vVy/Xu8J0dplZmKG6PO9/sd1Z+rM0KdLrTD26o+fkAWWA/DuPn9eajH2x1PEA62K/rjfALdwzMniQFYDPsu5zv198yv/JL5R/3Gde30q/9svH9WKC9+kTL0x1QfdJFhejWCH2u0yMgOJJI6EHMJgFCKMYlEKMYjEIfxm0zApni58VefoRVM9ZgCO0AE0IQhUqfbTcqCISgVHoEq1NBAD4DY2vJAA+rosv5dbj5sF5/5E1OtQE+rh2vVG5FYH/Q06UtLgesWbmTaUOWZ0Si5G64KOKt+/YgYsgPrd7CMDncDLNx4L7STBz16XEP8dvLDW7kc6ui8Q9OiT7aATT2snUkcjnbjr8chhPLm73f6zgIJbzh8vla5QInbB9GnLH/azdsvkgLgantDFOa9S05n2GP+vS0h/jKamjOkwzbLfN1Aj592ikOcByQXzHLGniG437zdoGDAYP4nN8N4+4R+Jyr7dI+5/6o0OdcQ7s/ZyId/JwhAOhzJhjwz5nDeP71X//y7E/PLySv6Pn8fqK+/UP9R/GjbY/79sOX7WK+V2774Z04dr+B6fj/XGzGnXD47u/i0V88LwfU6Wb8abZZ7O8T2z/s/9lSlhVXDHGQp6cN6I/wsNl//dehWBLvsyLo02kbd8zhOxZyymUTd8jn4xkrpkzbWGL+3BYJL5se3d1udTi9t3+o/k590P/51ZPF6nb415O//fdlsv+3J8//7cW//fXJV0/uFsPydvvkb789Oa+pWj+cHqx2u57vDv/7n6fN/jnMx33P7W+/Hbf+w9dPvvrt66/+8vzfXvz53//zP7/67bzz4Q+HfzgfY/qXw47Pnnz127Ov/vKXf/vjX/5c7fis2/FZtePzJ1/99pxKfN7t+Lza8cWTr357QSW+6HZ8Ue34xydf/fZHasc/djv+sdrxT0+++u1P1I5/6nb8U7Xjn5989dufqR3/3O3452rHvzz56re/UG/OX7od/1Lt+O9Pvvrt36kd/73b8d+rHf/65Kvf/krt+Ndux7/WJ8D+fHhGnjvP+pPnWXP2HE6fZ+TOxAlUn0HP9ufFM/IcetafRM/qs+jZ/tx49oLcuT+RntVn0rP9+fHsj+TO/cn0rD6bnu3PkWd/InfuT6hn9Rn1bH+ePPszufP/z9fd5kZ260AA3VAwaPFL5P43FvhKBtp1i/zbwvC9JGy7Rkei3k21/nbV+umVRftqvRtr/e2s9dMvi/bWejfX+ttd66dnFu2v9W6w9bfD5KdnhHaYvDtM/naY/PSM0A6Td4cJ/Ix6fkjxn1Lkx9TfDpOfnhHaYfLuMPnbYfLTM0I7TN4dJn87TH56Rvw/r3+fBX/43WHyt8Pkp2eEdpi8O0z+dpj89IzQDpN3h8nfDpOfnhHaYfLuMPnbYfLTM0I7TN4dJn87TH96RmmH6bvD9G+H6U/PKO0wfXeY/u0w/ekZpR2m7w5T+E34/CqkHabkl+HfDtOfnlHaYfruMP3bYfrTM0p/hum7w/Rvh+lPzyjtMH13mP7tMP3pGaUdpu8O078dpj89o7TD9N1h+rfD9KdnlHaYvjtM/3aY/fSM0Q6zd4fZ3w6zn54x2mH27jD722H20zNGO8zeHWZ/O8x+esZoh9m7wwzy1hO4aIcZiVx/O8x+esZo6rJ3h9nfDrPo8pO9G8z+NpjtLkLZu7/sb39ZdinK3u1lf9vLqs1R9m4v+9te/mlzlL/by/+2l682R/m7vfxve7m0Ocrf7eV/28u1zVH+bi//215ubY7yd3s5RHpvc5STVP+3vTzaHOXv/vK//eW7zVH+bjD/22CebY7yd4f53w7zanOUvzvM/3ZYfNocFe8Oi78dFqvNUfHusPjbYSFtjop3h8XfDgttc1S8Oyz+dlhYm6Pi3WHxt8PC2xwV7w4L+ItjtDkqyN8d/3ZY7DZHxbvD4m+HRbY5Kt4dFn87LKrNUfHusPjbYfvT5qj97rD9t8P2anPUfnfY/tthW9octd8dtv922NY2R+13h+2/HbatzVH73WH7b4dtb3PUfnfY/tthO9octd8dtmF7Yrc5apMdir8dtrPNUfvdYftvh+1qc9R+d9j+22H5aXNUvjss/3ZYrjZH5bvD8m+HpbQ5Kt8dln87LLXNUfnusPzbYfmEMLoJle8Oy78dlk8I2//p/re3/v3D7w7Lvx2WPz1jyX565rvD8m+H5U/PWP0X8i8X/C+/OyxhE+ynZ/xD/5nJPtjfDsufnnG6pZnvDsu/HVaf9l9YvTus/nZYrfZfWL07rP52WP30jAv7v13vDqu/HVba/99+d1j97bD66RmnO7L17rD622H17K3SXdl6d1j97bD66Rmnf0eod4fV3w6rn55x+sWod4fV3w6rp8M2/cPvDivYan06LOkfJrutuN360zRedMv9wzZcYcf189M3Qb8cZw3/PGy6fn5aJ/iW7Ydsu35g3/Xz0z1BG/Ws4Z+HrdfPTwMFbbezhn8edl8/Pz0UtOPOGv552ID9PJv6tOnOGv552IP9/HRS0L47a/jnYRv289NMQVvvrOGfh53YT7Xf9bOGfx7679nB5z+lFtvwf+34P/1Hu3/RPX/ov2cfv/n/z7b9cd//2coP/v1hO/+49f/s5m/uHWzzH3f/nw39zcmM7f8jADx7+pt/fxgBoAE82/qbf3+YAiADPDv7m39/GASgBDyb+5t/f5gFAAasZ39/8+8P4YAFHrCeLf6mf4gILCCB9ezyN/1PUGCBCqxno3/v/6z+uRn8edJ/AAPr2evf3GEIDSywgfVs92/e/0QHFvDAenb8u39/pP9ACNaz6d/9+yP9B0iwnn3/5L+/CBMscIL1bP0n//4RKVhABUv7iLcIFizQgvUAQPLvL/GCBWCwHgNI/v0lZLDADNbDAMm/v0QNFrDBeiQg+feXwMECOVgPBiT//hI7WIAH6/GA5L//CB8s8IP1kEDy3z9EEBYQwnpUIPn3hyDCAkVYDwwU71/iCAsgYT02ULx/CSUssIT18EDx/iOasIAT1iMExfuPgMICUVjW/11jEVNYgArrqAL/+UFYYYErrIcKivc/kYUFtLBs+PlHdGEBL6yHDMr/0/rnXvDnSf8BMaxjDPHz59fa8OdJ/wEzrEcOav/8efvg/z7pP5CG9eBBJf3zxBoWYMN6/KCK/vMTbljgDeuAw+fzU2Av+POk/4Ac1jGHz6J/nvQfqMM67PAR+udJ/wE8rCMPH6V/np3/gP47+PAx+udJ/wE/rOMPH6d/nvQfCMQ6BPEJ+udJ/wFCLD/OtemfJ/0HDrHinDdK9ueJRCygiPXowvoU/fOk/0Aj1gMMa9H+Ix6xACTWYwxrLfoFICaxACXW4wxr0QYkLLHAJdZDDWvRBiQysYAm1qMNa9EGJDixQCfWAw5r0QYkPrEAKNZjDmvRBiREscAo1sMOa236E5QwxQKnWPtga9IChCoWWMXa59QbbUGiFQu4Yu1z8I22IAGLBWKxHoRYQn8EErNYgBbrcYglTwdKCBQgLQhwsR6LWEJbkNDFArtYD0csoS1I9GIBX6xHJJbQFiSAsUAw1oMSS2gLEsNYgBjrcYklPMQSx1gAGSuHv4QQylhgGSv7reZFNGMBZ6xHKJq/hBLQWCAaK08H8hROUGOBaqzDGs2/ANKBABsrTwfyGE9sYwFurMcrlvIcT3xjAXCsxyyW8iBPjGMBcqzHLZbyJE+cYwF0rMculvIoT6xjAXasxy+W8ixNvGMBeKzHMJbyv0wS81iAHqvO6RP+t0niHgvgY9U5Bsy/icQ+FuDHejxjKe9k4h8LAGQ9prGUdyIxkAUIsh7XWMY7kTjIAghZj20s451ILGQBhqzHN5bxTiQesgBE1mMcy3gnEhNZgCLyIMcy2olCVERAReRRjmVU4oWwiACLyMMcfFtYCIsIsIh8zlEo2slCXETAReRzzqTTThYCIwIwIg90LKOdLERGBGREPtEnWyE0IkAj8jmNSL8KQmxEwEbksY7F5VcIjgjgiDzYsbj+CtERAR2RcxuCO6wQHhHgETk3IjinCvERAR+RcyuCk6oQIBEAEjk3IzirChESASGRczuC06oQIhEgErk3JHgrEyMRMBI5tyQ4sQpBEgEkkXNTgiurECURUBI5tyU4swphEgEmkXNjIngnEicRvDTxuMfi0Crs3gRenHjgY3FpFXZ34nV5opdiodcnoBEf+VicaoVdocA7FA99LG61wq5R4D0KOadEeSezqxR4l0LOdR3eyew6Bd6nOFpCc66wGxV4peLRD77bKOxSBd6qePSD7zYKu1cBWiKPfvDdRiFaIqAl8ugH320UoiUCWiKPfvDdRiFaIqAlotruNgrREgEtEbV2t1GIlghoiai3u41CtERAS0Sj3W0UoiUCWiK6291GIVoioCWi2e42CtESAS0RrXa3UYiWCGiJ2KfdbRSiJQJaIrba3UYhWiKgJWLS7jYK0RIBLRHTdrdRiJYIaImYDZmMcIkAl4h5u9sohEsEuEQs2t1GIVwiwCViu91tFMIlAlwilu1uoxAuEeASOdcy6G6jEC4R4BK5NzPobqMQLxHwEjm3M/huoxAwEQATOWBCdxuFgIkAmMgBE7rbKARMBMBEDpjQ3UYhYCIAJnLAhO82ChETATGRIyZ0t1GImAiIiRwxobuNQsREQEzkiAndbRQiJgJiIkdMItmRESFkIkAmcsiEblcKIRMBMpFDJvzMlBAzETATif7MlhAzETATOWbS/O2amImAmcgxk73+8/z3wS8RQRMBNJGDJvzYlRA1EVATOWrCz10JYRMBNpHDJvzglRA3EXATOW7SbHEQOBGAEzlwwo9uCYETATiRAyf87JYQOBGAEzlwsnmcJnIiICdy5GTzvxgSOhGgE9n96QUhdCJAJ/JISJPHiZwIyIk8EtLkcSInAnIij4Q0eZzIiYCcyCMhTR4nciIgJ/JISJPHiZwIyIkcOeF5nMCJAJxIfvo8TuBEAE4kV5/HCZwIwImk9HmcwIkAnMiBE57HiZsIuImk9XmcuImAm8hxE57HCZsIsIkcNuF5nKiJgJrIUROexwmaCKCJHDTheZyYiYCZyDETnscJmQiQiRwyafI4IRMBMpFDJjyPEzEREBM5YsLzOAETATCRAyY8jxMvEfASOV7C8zjhEgEukcMlPI8TLRHQEjla0uRxoiUCWiJHS5o8TrREQEvkaAnP4wRLBLBEDpbwPE6sRMBK9FgJzeNKqESBSvRQCc/jSqhEgUr0I20eV0IlClSih0poHlciJQpSokdKaB5XAiUKUKIHSmicVuIkCk6ix0n4EWwlTqLgJPrpNwWVMIkCk+ijHlz/lSiJgpLoURJ+BluJkigoia7++IISJFFAEl398QUlRqJgJHqMJJuZLaQFwUj0GAk/xa3ESBSMRFd/fkEJkSgQiT7iwXOkEiFREBJ9wIPnSCVAogAk+ngHz5FKfETBR/ThDp4jlfCIAo/oox08RyrREQUd0aMjNEcqwREFHNGDIzRHKrERBRtRkTZHKrERBRvRYyM0RyqhEQUa0UMjNEcqkREFGdEjIzRHKoERBRjRAyM0RypxEQUXUdltjlTiIgouopJtjlTiIgouolJtjlTiIooDp/TT5khlI6dw5pSuPkcqGzuFc6dU2hypbPLUa/SUtjlS6fApaMADIzRHKps/hQOoDozQHKlsBBXOoDowQnOksilUOIbqwAjPkcomUeEoqiMjPEcqm0aF46gOjdAcqWwgFdCIHhqhOVIJjSjQiB4a4TmS0IgCjeihkSZHEhtRsBE9NsJzJLERBRvRYyM8RxIaUaARPTTCcyShEQUa0UMjPEcSGlGgET00wq+CKbERBRvRxzqaEEJsRMFG9Fwl4SGE2IiCjei5SsJDCKERBRrRc5WEhxAiIwoyoo90NCGEyIiCjOgjHU0IITKiICN6r5LQbyCREQUZ0XuVhH4DCYwowIjeqyT0dwCBEQUY0XuVhH4BCYwowIjeqyT0C0hgRAFG9F4loV9A4iIKLqL3Kgn9AhIXUXARvVdJaAghLKLAInqukvAQQlhEgUX0sAgPIURFFFRE700S2n8ERRRQRO9NEh5CCIoooIjeqyS0AYmJKJiI3qsktAEJiSiQiN6rJLQBiYgoiIjeqyS0AQmIKICI3psktAGJhyh4iN6LJDyEEA9R8BA9HtKEEOIhCh6i5yoJDyHEQxQ8RO9VEtqCxEMUPETvTRL6I5B4iIKH6LlJkvZfrH+aEEIIiCiAiN6rJDzFEBFREBG9d0loDxMRURARPSKSzv8JSBMCieghER6DCIkokIgeEsn4z+LfEixAmhBMRI+J5OYFSBMCiui9TUK/hgRFFFBED4pwYFeiIgoqojnsCBIVUVARPSqS+Z/LP3VIYoRFFFhED4vwW+lKXETBRTSHKEhcRMFFNIcoSFxEwUW0hihIWESBRbSGKEhYRIFFtIYoSFhEgUW0hihIWESBRbSGKEhYRIFFtIYoSFhEgUW0hihIVERBRbSGKEhQRAFFtIYoSFBEAUW0hihIUEQBRezTR0EjKGKAIvbpo6AREzEwEfv0UdCIiRiYiH36KGjERAxMxD59FDRiIgYmYp8hChpBEQMUsU8fBY2YiIGJ2KePgkZMxMBE7NNHQSMmYmAi9umjoBESMSARW30UNEIiBiRia4iCRkzEwERsDVHQiIkYmIitPgoaIREDErHVR0EjJGJAIrb6KGiERAxIxNYQBY2YiIGJ2BqioBEUMUARW30UNIIiBihia4iCRlTEQEVM+ihoREUMVMRkiIJGWMSARUyGKGjERQxcxKSPgkZcxMBF7LgITXJGXMTARey4CB/vYwRGDGDEhvFaRmDEAEZM+vEyRmDEAEZM+vEyRmDEAEZM+vEyRmDEAEZM+/EyRmDEAEZM+/EyRlzEwEVM+/EyRlzEwEVM+/EyRlzEwEVM+/EyRlzEwEVM+/EyRlzEwEVM+/EyRlzEwEVM+/EyRljEgEVM+/EyRlTEQEVM+/EyRlTE8J0O68fLGHupA5/qsH68jLHHOvC1DuvHyxh7rwMf7LBhvIyxNztej3b042WMPtsBDWj9eBljL3fg0x3Wj5cx9noHPt9h/XgZYy944BMe1o+XMfaKBz7jYcN4GWMveYCKmA/jZYywiAGLmPfjZYywiAGLmPfjZYywiAGLmPfjZYywiAGL2GGRJogRFzFwEZtujBiBEQMYseHGiBEYMYARu2988CBGZMRARuxeGaFfAiIjBjJiR0aaIEZoxIBG7NBIE8SIjRjYiB0b4UGM2IiBjdixEb4nZwRHDHDEDo7wJEdwxABH7OAI35MzoiMGOmJHR/ikRiM6YqAjFkMUJDpioCN2dKSEHZMzwiMGPGLRXx42wiMGPGLRXx42wiMGPGK7vzxshEcMeMR2f3nYiI4Y6Ijt/vKwERwxwBHb/eVhIzhigCO2+8vDRnDEAEds95eHjeCIAY7Y7i8PG7ERAxux3V8eNkIjBjRiu788bIRGDGjEdn952IiMGMiIZX952IiMGMiIZX952AiMGMCIZX952IiLGLiIZX952IiLGLiI5XB52IiLGLiIZX952IiLGLiIZX952AiLGLCIZX952IiKGKiIZX952IiKGKiIZX952IiKGKiI1XB52AiLGLCI1XB52IiLGLiInesipf+5/dsJLUBgxABGrIZdQQIjBjBiB0bK/nP/5x/IAURGDGTEjoyU/+fxT/DXKKERAxqxQyMV/P8B6UKwETs2wvM0sREDG7FjI7X5PwFpQ8ARuzdG6O8RgiMGOOL3xgjN0050xEFH/F4ZYd9jJzrioCN+b4yw77ETHXHQET86wuOwEx5x4BE/PMLjsBMfcfAR//RnBZ3wiAOP+Kc/K+iERxx4xA+P8DTrxEccfMSPjxS9OesESByAxId3R5wAiQOQ+AMePIw6ARIHIPHHO3gYdeIjDj7iD3fwMOqERxx4xB/u4GHUCY848Ig/3MHDqBMeceARPzxS9V/YP0v4D0B8xMFH/OEO+fD3I4mPOPiIP9whH/5KKfERBx/x4yM0TzvxEQcf8eMjNE874REHHvF7aYTFGSc84sAjfi+N0B+DREccdMTvpRH6Y5DgiAOO+L00Qn8IERxxwBG/l0boDyGCIw444vfSCMvTTmzEwUb8XhphedqJjTjYiN9LIyyLOLERBxvxc2mE5mknNuJgI34ujfA87QRHHHDE760R2oAERxxwxO+tEdqABEcccMQf7JCP0J8hREccdMQf7ZCP8gKkBYFHfLg24oRHHHjEh2sjTnjEgUd8uDbihEcceMSnayNOfMTBR3y6NuIESByAxIdrI06AxAFIfLg24gRIHIDEh2sjToDEAUh8ujbiREgchMTt9KDRHiRC4iAkfu+N0G8RERIHIfF7b4T2MBESByHxe2+E9jAREgch8SMkPEsSIXEQEn/EQz50DowTInEgErchChIhcXzs/AgJ39h09t45Pnh+Lo7wLMmePMc3z8/FEZ4l2avn+Oz5uTjCsyR7+BxfPn/Ao8mS7O3z1+Pn3mdJ+vw5dOC9OEJ/BrAX0PEJ9HtxhP4MYI+g4yvo9+II/T3I3kHHh9DvxRH6DWZPoYOO+L04Qr/BBEcccMTvxRH6DSY44oAjfi+O0G8wsREHG/F7cYQGMWIjDjbix0Z4ECM04kAjfmiEBzEiIw4y4vfeCO0/IiMOMuL33ggPYkRGHGTE78UR2oBERhxkxO/FEdqAREYcZMTvxRHagERGHGTE78UR2oBERhxkxO+9EdqAREYcZMTvtREegwiNONCIHxppYhCxEQcb8WMjfGPTCY444IgfHOE5iuCIA474wRG+selERxx0xI+O8I1NJzziwCN+eIRvbDrxEQcf8RyiIPERBx/x4yN8Y9MJkDgAiR8g4VmSAIkDkPi9OMKzJBESByHxHKIgARIHIPEcoiABEgcg8XtxhG9sEiFxEBK/F0f4xiYhEgci8eyHWzohEgci8UMkPIwSInEgEj9E0mxsEiJxIBJ/xEM+dCihEyJxIBKvfrilEyFxEBI/V0d4GCVC4iAk/oBHE0YJkDgAiT/e0YRR4iMOPuIPdzRhlPCIA4/4wx1NGCU84sAjXsOuINERBx3xGnYFiY446Eh8+l3BIDgSgCPx6XcFg+BIAI7Ep98VDIIjATgSn35XMIiNBNhIfPpdwSA0EkAj8el3BYPQSACNxKffFQxCIwE0Ep9+VzCIjATISHz6XcEgMBIAI/EZdgWDyEiAjMTqdwWDyEiAjMTqdwWDyEiAjMS9OUIbkMhIgIzEvThCG5DISICMxLk4QsNoEBkJkJE4MsLDaBAZCZCRODdHeBgNIiMBMhLn5ggPo0FkJEBGYvUzBYPISICMxOpnCgaRkQAZCelnCgaRkQAZCRlmCgahkQAaCelnCgahkQAaCelnCgahkQAaiUMjPIgFsZEAG4ljIzyIBcGRABwJ6XcFg+BIAI6E9LuCQXAkAEdCzq4gnc0cREcCdCSk3xUMgiMBOBI67AoG0ZEAHQntdwWD6EiAjoT2u4JBcCQAR0L7XcEgNhJgI6H9rmAQGwmwkdB+VzCIjQTYSGi/KxjERgJsJLTfFQxCIwE0EtrvCgaRkQAZCe13BYPISICMhPW7gkFkJEBGwvpdwSAyEiAjYf2uYBAYCYCRsH5XMIiLBLhIWL8rGMRFAlwkrN8VDOIiAS4S1u8KBnGRABcJG3YFg8BIAIyE9buCQVwkwEXC+l3BIC4S4CLh/a5gEBYJYJHwflcwCIsEsEh4vysYhEUCWCR82BUM4iIBLhI+7AoGgZEAGAkfdgWDyEiAjIT3u4JBZCRARsKHXcEgNBJAI+HDrmAQGwmwkfBhVzAIjgTgSES/KxgERwJwJGLYFQyiIwE6EtHvCgbRkQAdiRh2BYPwSACPRPS7gkF4JIBHIvpdwSA8EsAjEcOuYBAfCfCRiGFXMIiPBPhIRL8rGMRHAnwkot8VDOIjAT4Se9gVDAIkAUAS++wK0uOOQYQkQEhi97uCQYQkQEhi97uCQYAkAEhi97uCQXwkwEdi97uCQXgkgEdi97uCQXgkgEdi97uCQXQkQEdi97uCQXAkAEdi97uCQWwkwEYih11BYiMBNhI57AoSGgmgkchhV5DQSACNRA67gkRGAmQkctgVJDISICORw64gkZEAGYkcdgUJjATASOSwK0hcJMBFIoddQeIiAS4SOe0KEhgJgJGoYVeQuEiAi0QNu4KERQJYJGrYFSQsEsAiUcOuIGGRABaJGnYFCYsEsEjUtCtIXCTARaKmXUECIwEwEvelEdqCBEYCYCQOjPAgRmAkAEZiuDYSBEYCYGQfGOH3uDeRkQ0ysqeXRjahkQ00soeXRjahkQ00su+9EXqPexMb2WAj+9OPmN7ERjbYyD42wpPcJjiyAUf2wRGe5DbRkQ06so+O0CS3iY5s0JF9dITf496ERzbwyP70UXATHdmgI3sNUXATHtnAI3udKEhnK27iIxt8ZK8+Cm7iIxt8ZK8+Cm7iIxt8ZK8+Cm7iIxt8ZK8+Cm7CIxt4ZK8+Cm6iIxt0ZK8+Cm6CIxtwZA/XRjbBkQ04sodrI5vgyAYc2cO1kU1wZAOO7OHayCY2ssFG9nBtZBMb2WAje7g2somNbLCRPVwb2YRGNtDIHq6NbCIjG2RkD9dGNpGRDTKyh2sjm8jIBhnZw7WRTWBkA4zs6drIJjKyQUb2cG1kExjZACN7uDayCYxsgJGtfRTcBEY2wMjWPgpuAiMbYGRrHwU3gZENMLJ1iIKbyMgGGdk6RMFNaGQDjWzto+AmNLKBRrb2UXATGtlAI1v7KLgJjWygkW1TFCQ2ssFGtk1RkODIBhzZNkRBgiMbcGTbFAWJjmzQkT28NrKJjmzQkW1TFCQ8soFHtk1RkPjIBh/ZNkRBwiMbeGTbFAWJj2zwkW1DFCQ+ssFHtk9RkADJBiDZD3jIotMdNxGSDUKyfYiCREg2CMn2IQoSINkAJNuHKEh8ZIOPbB+iIOGRDTyyfYiChEc28Mj2IQoSHdmgI9uHKEhwZAOObB+iILGRDTayY4iCxEY22MiOIQoSGtlAIzuGKEhoZAON7BiiIJGRDTKyY4iCREY2yMiOIQoSGdkgIzuGKEhgZAOM7BiiIHGRDS6yY4iCxEU2uMiOKQoSGNkAI3sPUZC4yAYX2XuIgoRFNrDI3kMUJCyygUX2HqIgYZENLLL3EAUJi2xgkb2nKEhcZIOL7D1FQQIjG2Bk7yEKEhjZACN7D1GQwMgGGNl7iIIERjbAyM5hmMwmMrJBRnb2w2Q2kZENMrKzHyaziYxskJE9vDayiYxskJGd/YjpTWRkg4zsRzpk0bmCm9DIBhrZ2c8V3IRGNtDIfqhDlrA5HpvYyAYb2dnPFdzERjbYyM5+ruAmNLKBRnb1cwU3oZENNLKrnyu4CY1soJFd/VzBTWhkA43sQyN8lMsmNrLBRvbw2sgmNrLBRvbw2sgmNLKBRvbw2sgmMrJBRvbw2sgmMrJBRvbw2sgmMrJBRvbw2sgmMrJBRvKBDln6X9S/z+fvf8AkMpIgI3nvjLCfIUlgJAFG8t4ZYTkqCYwkwEjeOyMsRyVxkQQXyXtnhP0SS+IiCS6S97kR1sBJWCSBRfK+NkJzVBIWSWCRvM+NsA5OwiIJLJL30gjr4CQqkqAi+ShHM4klCYsksEg+ytFMYknCIgkskvfWCPsOJVGRBBXJe2uEfYeSqEiCiuS9NUK/AkRFElQk760RmuSSsEgCi+S9NkKTXBIXSXCRXP1ZwSQukuAiufq5gklcJMFF8j43wn6KJ3GRBBfJe2mEJrkkMJIAIymffhJLEhlJkJGUPgomkZEEGUnpo2ASGUmQkRxeG0kiIwkyksNrI0lkJEFGUk4UNBYFk9BIAo3k8NpIEhpJoJGUYcR0EhtJsJGUPgomsZEEG0npo2ASGkmgkdQ+CiahkQQaSe2jYBIaSaCR1D4KJqGRBBpJ7UdMJ6GRBBpJ7UdMJ6GRBBpJ7UdMJ5GRBBlJ7UdMJ4GRBBhJ7UdMJ4GRBBhJ7UdMJ4GRBBhJ7UdMJ4GRBBhJ60dMJ3GRBBdJ60dMJ2GRBBZJ60dMJ2GRBBZJ60dMJ1GRBBVJG0ZMJ2GRBBZJ60dMJ1GRBBVJ60dMJ0GRBBRJ60dMJ0GRBBRJ60dMJzGRBBNJ60dMJzGRBBNJH0ZMJzGRBBNJH0ZMJzGRBBNJH0ZMJ0GRBBRJ70dMJ0GRBBRJH0ZMJ1GRBBVJH0ZMJ2GRBBZJH0ZMJ3GRBBdJH6IgcZEEF0kfRkwngZEEGEnvdwWTwEgCjGQMu4JJZCRBRjKGKEhkJEFGMoYoSGQkQUYyhhHTSWgkgUYyhhHTSWwkwUYy+hHTSWwkwUYy+hHTSWwkwUYyhhHTSXAkAUfywQ5ZdK5gEh1J0JGM/gZxEhxJwJHc/YjpJDiSgCO5+xHTSXAkAUdy9yOmk+BIAo7k7kdMJ8GRBBzJ3Y+YToIjCTiS970R+lOI2EiCjeR9b4T+ECE0kkAjed8boVmA0EgCjeS9M0J/hhAaSaCRvHdG6M8QQiMJNJL3zgj9BhMZSZCRzGFXkMhIgoxkDruCREYSZCRz2BUkMpIgI5nDriCRkQQZyRx2BQmMJMBI5rQrSGQkQUYyh11BAiMJMJI57AoSGEmAkbyXRmgDEhhJgJG8d0ZoAxIYSYCRvHdGaAMSGEmAkbx3RngYJTKSICN5L43wMEpkJEFG8t4aoS1IZCRBRvLICA9iREYSZCSPjPAcRWQkQUbyvjXCcxShkQQayXtphLYgoZEEGsl7aYS2IKGRBBqpSyPxX3z+rb+/w4vISIGM1JERnsOK0EgBjdShEZ7DithIgY3Up98ULGIjBTZSx0b4MbkiOFKAI3XfGmHfwiI4UoAjde+M0CBXBEcKcKQ+B4jpKJgiOlKgI/VoBw9yRXSkQEfqwQ4e5IrgSAGO1HlrhAa5IjZSYCN13hqhQa6IjRTYSJ23RmiQK2IjBTZS58YIDXJFbKTARuqhDln09nMRGymwkVp9EixCIwU0UqtPgkVopIBGavVJsAiNFNBIrT4JFqGRAhqp1SfBIjJSICMlfRIsAiMFMFLSJ8EiMFIAIyV9EiwCIwUwUtInwSIwUgAjJX0SLAIjBTBS0ifBIi5S4CIlQxIsAiMFMFJyfgQWOyNTBEYKYKTOOC2hr+0UkZECGal7a4R+BYiMFMhI3Usj9CtAZKRARuqRDhF6TKkIjRTQSA23RorQSAGN1HBrpAiNFNBIPdQhQo85FbGRAhupe22EfgmJjRTYSN1bIzQNF8GRAhype2uEpuEiOlKgI6X9WMEiOlKgI6X9WMEiOlKgI2X9WMEiOlKgI2WnB5X+JyQ8UsAjNT02UsRHCnykzmMjQoW2CJAUAEkNj40U8ZECH6nhsZEiPlLgI2XDLJkiQFIAJGXDLJkiQlIgJGX9LJkiQlIgJDXcGikiJAVCUg94iNBtySJCUiAk9YBHk2YJkBQASZ3XRniaJT5S4CN1Lo3wNEt8pMBH6lwa4WmW8EgBj9S5NMLTLNGRAh2pc2mEp1mCIwU4Uve1EfpTiOBIAY7UvTRCfwoRGymwkbqXRuhvYmIjBTZS99II/RFAaKSARupeGqE/AgiNFNBI3Usj9AtIaKSARupeGqFfQCIjBTJS99IIDaMERgpgpO6lERpGCYwUwEjdSyP0tyCBkQIYqfvaCO0/4iIFLlL30ggPo8RFClykYoiCxEUKXKT2EAWJixS4SO3+qGARFylwkdr9UcEiLlLgIrX7o4JFXKTARWoPRwWLwEgBjNQejgoWkZECGanhsZEiMlIgI7V7Hy4iIwUyUrs/KlhERgpkpPZwVLAIjRTQSN1bI7QFCY0U0EjdSyO0BQmNFNBI3UsjtAUJjRTQSN1LI7QFCY0U0Ejl+csIfaWiiI0U2Eg91tGEEGIjBTZSD3U0IYTQSAGN1EMdTQghNFJAI3XujPAQQmikgEbq3BnhIYTQSAGN1LkzwkMIoZECGqlDIzyEEBopoJE6NMJDCJGRAhmpIyM8hBAYKYCRuldG6BeQwEgBjNS9MkK/gARGCmCk7pUR+gUkMFIAI3WvjNAvIHGRAhepe2WEhhDiIgUuUvfKCA0hxEUKXGR97jMj7FfAXfxb4fvD3xKrDSJ38VViYQnps8hdfdUQrKFtHLmLrxKKJaxNJHfxVcKwhLeh5C6+SjiWiDaX3MVXicASu40md/FVYmOJ7NPJXX3VSKxRfUC5q68a2KD3GRLeoERNvj/8LbHamHIXXyWwQVc//Pcuvkpgf65h/u9dfdXABl39ts1dfJXABl39zs1dfJXABl39mxB38VUCG3T1z0LcxVcJbNB1trIpB97VVw1s0NUf7bqLrxLYn9Kf7rqLWEKwP6U/4HUXXyWwP6U/43UXXyWwP6U/5nUXXyWwPaU/6XUXXyWwPaUnvrv4KoHtKb3y3cVXCWxP6aHvLr5KYHtKb3138VUCu1N67ruLrxLYndqL313EEordqT363cVXCexO7d3vLr5KYHdqT3938VUCu1N7/buLrxLYndoD4F18lcDu1MEA7+qrBran9gfC7uKrBLan9mfC7uKrBLan9sfC7uKrBLan9SfD7iKWMGxP6w+H3cVXCWxPG86H3dVXDexPG46I3dVXDWxQ60+J3cVXCWxQ6w+K3cVXCWxQ68+K3cVXCexPG46L3dVXDWxQ60+M3cVXCWxQ6w+N3cVXCWzQc4+liTpEab4//C2xhqhDoOb7w98S8kQdenDmrr5qYIM+/NJFHeI13x/+lrAh6hCy+f7wt4QPUYeozfeHvyViiDoEbr4//C2xh6hD7Ob7w98SOUQdwjffH/6WqCHqEMH5/vCWuIbDv6sEcb4//C2xhqhDHOf7w98SMkQdQjnfH/6W0CHqEM35/vC3hA1Rh4DO94e/JXyIOsR0vj/8LRFD1CGs8/3hb4k9RB0iO98f/pbIIeoQ2/n+8LdEDVGH8M73h7fEBZ4m6hDi+f7wt8Y5a1FspsldfdXA/rzQw1ucSM/3h78ldIhLBHu+P/wtYUNcItzz/eFvCR/iEgGf7w9/S8QQl4j5fH/4W2JPcYm4z/eHvzVyikvEfr4//K3xDCvRT9MarEU3tmhOu0tEgL4//C0x7S4RBPr+8LfE8/tdF/8nIRD0/eFvDR1iG7Gg7w9/SzwapNL832AtmtiiZ4yY0hlEd/VVA3v0XJjp4iNhoe8Pf2vsIT4SGfr+8LdEDvGR4ND3h78lqj/mdFdfNbBF71P09KTTXcUahT16mKiJscSJvj/8LSFDjCVU9P3hb4nn1JrSU2t39VUDe/QBoC7GEjH6/vC3hA8xlqDR94e/JWKIscSNvj/8LbGHGEvo6PvD3xI5xFiiR98f/paoIcYSQPr+8JRYV5Doz7/FBGmhIK07d4z+7FpMkBYK0rqjx+jv+MUAaSEgrTt9jP7IWAyQFgLSugPI6I+MxQBpISCt+249/aouBkgLAWndp+vpV3UxQFoISOu+Xk9j7GKAtBCQ1gEkHmMX86OFfrSOH/EYuxgfLeSjdfmIdyfjo4V8tO5IMh5jF/OjhX60lgwxdjFAWghIaw3AuZgfLfSjtQbgXMyPFvrRWgNwLuZHC/1orQE4F/OjhX601gCci/nRQj9aawLOxfxooR+tNQHnYoC0EJDWGVfWxNjFBGmhIK1zMYfH2MUEaaEgrTu0jH9RmCAtFKQlOsTYxQhpISGtO7uM/ypghLSQkNYZX9bE2MUMaaEhrUeEuhi7GCItRKQl0y7oYoq0UJGWDLugiynSQkVaMuyCLqZICxVpHUVqYuxijLSQkdZhpCbGLuZICx1paX9c7i6+SmCPan9i7i6+SmCLnhs8Sk/u39VXDexR7c/N3cVXCWxR7Y/O3cVXCexQ7U/P3cVXCWxQ7Q/Q3cVXCWxQ7c/Q3cVXCWxQ64/R3UUsgY60rD9JdxdfJbA9rT9MdxdfJbA9rT9PdxdfJbA9rT9SdxdfJbA7rT9VdxdfJbA7rT9YdxdfJbA7rT9bdxdfJbA7rT9edxdfJbA7rT9hdxdfJbA7fThjtxgiLUSk5cMZu8UQaSEiLZ/O2C2GSAsRafkUQRkiLUSk5VMEZYi0EJGWTxGUIdJCRFo+RVCGSAsRafkUQRkiLUSk5WMEZYq0UJGWjxGUMdJCRlox7IIuxkgLGWnFsAu6GCMtZKQVwxm7xRhpISOtmM7YLeZICx1pxXDGbjFHWuhIK4Yzdos50kJHWjGcsVvMkRY60orhjN1ijrTQkdaZnab0fsBdfdXABh3Gp93FVwnsz2GC2l3EEuhIaxiidhdfJbA/hzlqd/FVAvtzGKV2F18lsD2HaWp38VUC23MYqHYXXyWwPYeZanfxVQLbcxirdhdfJbA9h8lqd/FVArtzGK52F18lsDuH+Wp3EUugIa1hxNpdfJXA7hymrN3FVwnszmHQ2l18lcDuHGat3cVXCezOYdzaXXyVwO6cJq7d1VcNbM9h6NpdfJXA9hzmrt3FVwlsz2H02l18lcD2HKav3UUsgXy0hgFsd/FVAttzmsF2V181sD+nMWx39VUDG3SYxHYXXyWwQYdhbHfxVQIbdJjHdhdfJbA/p5Fsd/VVAxt0mMp2F18lsEGHwWx38VUCGlQ+wxk7YYAkCEjyGc7YCQMkQUCSzzF4fp1AmCAJCpJ8hjN2wgRJUJDkM5yxEyZIgoIkn+GMnTBBEhQk+Qxn7IQJkqAgyWc4YydMkAQFST7DGTthgiQoSPIZztgJEyRBQZI1nLETJkiCgiRrOGMnDJAEAUnWcMZOmB8J+pGs4YydMD8S9CNZwxk7YX4k6EeyhjN2wvxI0I9kDWfshPmRoB/JGs7YCfMjQT+SNZyxE8ZHgnwkazhjJ0yPBPVIZDpjJ0yPBPVIrh7x9mR6JKhHcvSIRx1heiSoR3KGu/GoIwyPBPFIDh7xqCMMjwTxSKSfrnUXXyWwPWUYsHVXXzWwP2WYsXVXXzWwQaUfs3UXXyWwQaWftHUXXyWwQbUftnUXsQTSkRw6aqKOMDoSpCO5dMQblNGRIB3JpSPeoIyOBOlIzhWkJuowORKUI9F+DOtdfJXABtWDm/w6gTA6EqQjeSCoizqMjgTpSLR/pOkuvkpgf2r/TtNdfJXA/rT+qaa7iCWQjsT615ru4qsEtqf1DzbdxVcJbE/r32y6i68S2J7WP9t0F18lsD2tf7npLr5KYHta/3jTXXyVwO60/v2mu/gqgd1p/RNOd/FVArvT+lec7uKrBHan9w853UUsgXQk3r/ldBdfJbA7vX/O6S6+SmB3ev+i0118lcDu9OFRp7v6qoHt6f27TnfxVQLb0/unne7iqwS2p/evO93FVwlsT+8feLqLrxLYnt6/8XQXXyWwPWN45umuYg2UI4nhpae7+qqBDXroqIk6jI4E6UguHfEGZXIkKEcSw9klYXIkKEdy5aiJOoyOBOlILh3xBmV0JEhHcumINyijI0E6kujna97FVwls0OhHbN7FVwls0H0O1xWPOoyOBOlIdj9o8y6+SmB/7n7W5l18lcD+3P24zbv4KoH9ufuJm3fxVQL7c/dDN+/iqwS25+7nbt7FVwlsz92P3ryLrxLYnrufvnkXXyWwPXc/gPMuvkpge2Y/g/MuYgmkI8l+DOddfJXA7sx+EuddfJXA7sx+GOddfJXA7sx+HuddfJXA7sx+JOddfJXA7sx+KuddfJXA7sx+MOddfJXA7sxhNuddfdXA9sx+POddfJXA9qx+QuddxBJIR1L9kM67+CqB7Vn9nM67+CqB7Vn9qM67+CqB7VnDtM67+qqB/VnDwM67+qqBDVr9zM67+CqBDVr92M67+CqBDVr95M67+CqB/VnD8M67+qoBDaqffn7nXYQSinSkn36E5118lVhYYjiWrEyOFOVIP8OxZGVypChH+jiQ2IdGHWV0pEhH+hmOJSujI0U60s9wLFkZHSnSkX6GY8nK6EiRjvQzHEtWRkeKdKSf4ViyMjpSpCNdw7FkZXSkSEe6hmPJyuhIkY50DceSldGRIh3pGo4lK6MjRTrSNRxLVkZHinSkaziWrIyOFOlI13AsWRkdKdKRruFYsjI6UqQjXcOxZGV0pEhHuoZjycroSJGOVIZjycrkSFGOVIZjycrkSFGOVKZjycroSJGOVIZjycroSJGOVIZjycroSJGO9Nw7Mvo0zV191cD+vHbEW5zRkSId6aUj3uJMjhTlSK8c8RZncqQoR/o4kJg0/zJYgyIdqU67S8rsSNGOVKfdJWV2pGhHqsPukjI7UrQj1WF3SZkdKdqR6rC7pMyOFO1IddpdUoZHinikOuwuKbMjRTtSHXaXlNmRoh3pI0FiytuL4ZEiHul9Roh/URgeKeKR3peE+BeF4ZEiHul5TMj4UARleqSoR/pYUBfbmB4p6pE+FtTFNqZHinqkjwV1sY3pkaIe6WNBXWxjeqSoR/pYUBfbmB4p6pE+FtTFNqZHinqkV4/4953pkaIe6dUj/n1neqSoR3r1iP9eZHqkqEd69Yh/3ZkeKeqRXj3iX3emR4p6pEePmtjG9EhRj/ToURPbGB4p4pEePGpiG8MjRTzSg0dNbGN4pIhHet8d4r+NGB4p4pFePOLdyfBIEY/04lET25geKeqRXj3i7cnwSBGP9OIRb09mR4p2pNeOeHsyO1K0Iz121EQuZkeKdqTHjprIxexI0Y702FEXl5gdKdqRHjvq4hLDI0U80vswEW9QhkeKeKQXj3iDMjxSxCO9eMR/fDI8UsQjPfPrurjE8EgRj/Q8UtTEJYZHinikZ3xdE5cYHinikT4UxJ+/vouvEtigZ3xdMwNAmR4p6pGei0fNDABlfKTIR7qHi3HK+EiRj3QPF+OU8ZEiH+k++ZPPAFDmR4p+pHu4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKfMjxT9SHO4GKeMjxT5SHO4GKeMjxT5SGu4GKeMjxT5SGu4GKeMjxT5SGu4GKeMjxT5SGu4GKeMjxT5SGu4GKdMjxT1SGu4GKcMjxTxSGu6GKdMjxT1SGu4GKdMjxT1SGu4GKdMjxT1SGu4GKcMjxTxyD7DxThjeGSIR/YZLsYZwyNDPLLPdDHOmB4Z6pF9potxxvjIkI/sM1yMM6ZHhnpkn+FinDE9MtQj+wwX44zpkaEe2We6GGeMjwz5yD7DxThjfGTIR/YZLsYZ4yNDPrIHg5rUZoyPDPnIDh81qc2YHxn6kR0/alKbMUAyBCS7jx/x7xoDJENAsvv2Ef+uMUAyBCRbZ4eejzMwJkiGgmSPBzWpzZggGQqSPR7UpDZjgmQoSPZ4UJPajAmSoSDZ40FNajMmSIaCZOftI57ajAmSoSDZefuIpzZjgmQoSHYEiac2Y4BkCEh2AImnNmOAZAhIdgCJpzZjgGQISHbfPuI/dZgfGfqR3beP+E8d5keGfmT37SP+VWV+ZOhHdt8+4l9V5keGfmT37SOa2ozxkSEf2X37iKY2Y3pkqEd23z7ivxQZHhnikV084t3J8MgQj+zgUZPajOmRoR7Z0SOe2ozpkaEe2X38iLcnwyNDPDIdeNMYHhnikenAm8bwyBCPTAfeNGZHhnZk9+2jJrUxPDLEI7uPHzWpjemRoR6ZDYM/jeGRIR6ZDYM/jeGRIR6ZDbPnjeGRIR7ZuXrUpTamR4Z6ZPfxI96gTI8M9cju40e8QZkeGeqR3cePeIMyPTLUI7tvH/EGZXpkqEdmx9/5OANjfGTIR/ZgUBd1GB8Z8pE9GNRFHcZHhnxkDwZ1UYfxkSEf2YNBXdRhfGTIR3bePmqiDuMjQz6y8/ZRE3UYHxnykV0+4t9VxkeGfGSXj/h3lfGRIR/Z4aMm6jA+MuQju28f8a8q0yNDPbL79hH/qjI9MtQju28f8a8q0yNDPbL79hH/qjI9MtQju28f8ajD9MhQj+y+fcSjDtMjQz2y+/YR/03C8MgQj+ziEe9OZkeGdmTXjpqow/DIEI/s4FETdRgeGeKR3cePeHsyPDLEI7uPH/H2ZHZkaEd27KiJOsyODO3I7tNHvD2ZHRnakd2nj5qow/DIEI/svn3URB2GR4Z4ZPfxI96gzI4M7ciuHfEGZXZkaEd27Yj/+GR2ZGhHdq4edVGH2ZGhHdm5e9REHWZHhnZk5+5RE3WYHRnakT0S1G1QMTsytCM7d4+6DSqGR4Z4ZOfyUbdBxfTIUI8sh8kMxvTIUI/s6FHkf1b/3AxrsA5FPrL79BH/vjI+MuQjO3yU+Z/LP/XXfxXWouhHloc3+YQIY4BkCEiWA28aAyRDQLIaeNMYIBkCktXAm8YAyRCQrAbeNAZIhoBkNfCmMUAyBCSrgTeNAZIhIFkNvGkMkAwByWrgTWN+ZOhHVgNvGvMjQz+yGnjTmB8Z+pHVwJvG/MjQj/wz8KYzP3L0I/8MvOnMjxz9yD8DbzrjI0c+8s/Am870yFGP/DPwpjM9ctQj/wy86UyPHPXIPxNvOuMjRz7yz8CbzvTIUY/8M/CmMz1y1CP/DLzpTI8c9cjXwJvO9MhRj3wNvOkMjxzxyNfEm87wyBGPfE286UyPHPXI18CbzvTIUY98DbzpDI8c8cjXwJvO8MgRj3xNvOlMjxz1yNfAm870yFGPfA286UyPHPXIZeBNZ3rkqEcuE2864yNHPnKZeNOZHzn6kcvAm878yNGP/PhRkx6dAZIjILkMs8GcAZIjIPkBpCY9OhMkR0Hyx4PE+NANZ4TkSEj+gFCTHp0RkiMh+QNCTXp0RkiOhOQPCDXp0RkhORKSPyDUpEdnhORISP6AUJMenRGSIyH540FNenQmSI6C5EeQeHp0JkiOguRHkHh6dCZIjoLkR5B4enQmSI6C5EeQeHp0JkhfH/6WyD49OhMkR0HyI0hNemSA5AhIfgCpSY/Mjxz9yO+rRzw9Mj9y9CO/rx7x9Mj8yNGP/I6u47+cmR85+pEfP2rSI+MjRz7yw0ddemR+5OhHfvyoSY/Mjxz9yI8fNemR+ZGjH/nxoyY9Mj9y9CM/t4+a9Mj4yJGP/Nw+atIj4yNHPvL77FGTHpkfOfqR33ePmvTIAMkRkPzhIHE+W8GZIDkKkj8eJM6vBzsjJEdCch/2QJ0RkiMhuQ97oM4IyZGQ3Ic9UGeE5EhI7tMeqDNDcjQk92EP1JkhORqSx7AH6syQHA3JY9gDdWZIjobkMe2BOkMkR0TymPZAnSmSoyJ5DHugzhTJUZE8pj1QZ4zkyEgewx6oM0ZyZCSPaQ/UGSM5MpKft4+c32B35kiOjuTT20fOHMnRkXx6+8iZIzk6kk9vHzlzJEdH8untI2eO5OhIPr195IyRHBnJp7ePnCmSoyL59PaRM0VyVCSf3j5ypkiOiuTT20fOFMlRkXx6+8gZIjkikk9vHzlDJEdE8untI2eI5IhIPr195AyRHBHJp7ePnBmSoyH59PaRM0JyJCSf3j5yRkiOhOTT20fOBMlRkHx8+8gZITkSkk9vHzkTJEdB8untI2eA5AhIPr195AyQHAHJp7ePnAGSIyD59PaRM0ByBCQf3z5yJkiOguTj20fOCMmRkHx6+8gZITkSkk9vHzkjJEdC8untI2eE5EhIPr595MyQHA3Jp7ePnBmSoyH59PaRM0NyNKSY3j4KZkiBhhTT20fBDCnQkOK8feR8mkowRApEpJjePgqGSIGIFNPbR8EQKRCRYnr7KBgiBSJSTG8fBTOkQEOK6e2jYIYUaEgxvX0UzJACDSmmt4+CGVKgIcX09lEwQwo0pJjePgpmSIGGFNPbR8EIKZCQYnr7KJggBQpSTG8fBROkQEGK6e2jYIIUKEgxvX0UTJACBSmmt4+CAVIgIMX09lEwQAoEpJjePgoGSIGAFOPbR8EEKVCQYnr7KBggBQJSTG8fBfOjQD+K6e2jYH4U6EcxvX0UjI8C+Simt4+C8VEgH8X49lEwPgrkoxjfPgrGR4F8FNPbR8H4KJCPYnr7KBgfBfJRTG8fBeOjQD6K8e2jYH4U6EcxvX0UzI8C/Simt4+C+VGgH8X09lEwPwr0o5jePgrmR4F+FOftI+fj1oIBUiAgxfT2UTBACgSkOIBU8p/Xv89KrMEaFAUpdPDNYIIUKEhhg28GE6RAQQobfDOYIAUKUtjgm8EEKVCQwgbfDCZIgYIUNvhmMEEKFKSwwTeDAVIgIIUNvhkMkAIBKWzwzWCAFAhIYYNvBgOkQEAKG3wzGCAFAlL44JvBACkQkMIH3wzmR4F+FD74ZjA+CuSj8ME3g+lRoB6FD74ZDI8C8Sh88s1gehSoR+GDbwbTo0A9Ch98M5geBepR+OCbwfAoEI/CB98MhkeBeBQx+GYwPArEo4jJN4PpUaAeRUy+GUyPAvUojh6V/uf2bye2BtOjQD2KGHaXgulRoB7F0aOy/9z/+cewButQ1KM4elT+n8c/ef12ZnwUyEdx+Kii+f/BehT5KKYRdsH0KFCP4txCqt38o7AmRT6KPUVQxkeBfBR7jKDMjwL9KPYUQZkfBfpR7CmCMj8K9KPYh+D9v6h/nw/+C2WAFAhI8XCQeDQ1WI+iIMURpAZ8gxFSICHFIaQGfIMZUqAhxR7e6ApmSIGGFHt4oyuYIQUaUhxDarA2GCIFIlKcm0jOrzsHU6RARYocpigHU6RARYocpigHU6RARYocpigHU6RARYocpigHU6RARYocpigHQ6RARIocpigHQ6RARIocpigHQ6RARIocpigHQ6RARIoapigHQ6RARIoapigHQ6RARIoapigHM6RAQ4oapigHI6RAQooapigHI6RAQooapigHI6RAQooapigHI6RAQooapigHE6RAQYoapigHE6RAQYqapigHI6RAQtqfYYryZoS0kZD2Z5iivBkhbSSk/RmmKG8mSBsFaX+GKcqbCdJGQdqfYYryZoK0UZD2Z5qivBkhbSSk/ZmmKG9mSBsNaZ97SE0k3wyRNiLS/gy7oJsh0kZE2geRmki+mSJtVKR9FKmJ05sx0kZG2oeReJzejJE2MtI+jMSj8GaMtJGR9h1jx6PwZo600ZH2nWPHv2zMkTY60r43kfiXjTnSRkfaa4qgm0HSRkjaa4qgm0nSRknaa4igm0nSRknaa4igm0nSRkna5yqS8/vOm0nSRknajws18XEzSdooSftIUrMrvBklbaSkLUME3YySNlLSliGCbkZJGylpyxBBN6OkjZS0ZYigm0nSRknaMkTQzSBpIyRtGSLoZpC0EZK2DBF0M0jaCElbhwi6GSRthKStQwTdzJE2OtLWIYJu5kgbHWnrEEE3c6SNjrR1iKCbOdJGR9o6RNDNHGmjI20dIuhmjLSRkbYOEXQzRtrISFuHCLqZIm1UpK1TBN2MkTYy0rYpgjJG2shI26YIyhhpIyNtmyIoY6SNjLRtiqCMkTYy0rYpgjJG2shI28YIyhxpoyNtGyMog6SNkLRtjKBMkjZK0rYpgjJJ2ihJ28YIyihpIyXtQ0nNrvBmlrTRkvaxpC7GMkzaiEnbh2GLm2HSRkzaB5OaXeHNNGmjJm0f3pLbTJM2atL26S25zTRpoyZtH96S20yTNmrS9uEtuc00aaMmbc9hV3gzTtrISfvBoW5XeDNP2uhJ+3hSF8kZKG0EpX1AqYvkDJQ2gtI+oNREcuZJGz1pH09qIjnjpI2ctA8nNbvCm3nSRk/acfbq+UX0zTxpoyftGOZ9b8ZJGzlpX05qYj3jpI2ctB8c6mI946SNnLQfG+piPdOkjZq0z2WkJtYzTdqoSftcRmpiPcOkjZi0z2WkJtYzTNqISftgUhPrGSZtxKR9Zto1sZ5Z0kZL2vcyEs9NjJI2UtK+l5H4j1AmSRslad/LSPxHKIOkjZC072Uk/iODQdJGSNr3MhL/kcEgaSMk7XsZicd65kgbHWnfy0g81jNG2shI+15G4omHMdJGRtrnMlIT6xkjbWSkfS4jdbGeOdJGR9r3NhJvT+ZIGx1p39tIvD2ZI210pH0vI/H2ZI600ZH2vYzE25M50kZH2vcyEm9P5kgbHWnfy0hNrGeQtBGS9r2N1MR6JkkbJWkfSepiPaOkjZS073Uk3uSMkjZS0j6U1MV6ZkkbLWkfS+piPcOkjZi0DyZ1sZ5p0kZN2vdCEv/CMk3aqEn7aFIX6xknbeSkfS8k8V9JTJM2alLeC0k81ifjpEROynsjiX7pk3FSIifl4SQe65NxUiIn5UeHWJ/MkxI9KT82xPpkoJQISnlAqYn1yUApEZTygFIT65OBUiIo5WeYS5/MkxI9KT/DXPpknpToSXk8qYn1yTwp0ZPyvIsUfBpHMk9K9KRcw259Mk9K9KR8dEiW/Lfln0ZiDdakCEq5ht36ZJ6U6Em5ht36ZJ6U6Em5ht36ZJ6U6Em5ht36ZJyUyEm5ht36ZJqUqEl5NKnqv7B/lq//rKxDkZNyDdfmknFSIielDNfmkmlSoialDNfmkmlSoialDNfmkmFSIialDNfmkmFSIialDNfmkmFSIiblQ0OylP8UZpqUqEl5H0biP7qYJiVqUt6HkehfL5JpUqIm5dUk+teLZJqUqEl5NYkmr2SalKhJeTSJ//UimSYlalIeTWr+epGMkxI5Ke/LSLzFGSclclLel5F4izNOSuSkfHBIPsJ/ZDBPSvSkfHRIPtrUYA2KoJTT00jJQCkRlHJ6GikZKCWCUk5PIyUDpURQyvFppGSglAhKOT6NlEyUEkUpp6eRkolSoijl9DRSMlFKFKWcnkZKJkqJopTj00jJSCmRlNJOhxrvUEZKiaSUNuzWJxOlRFFKG3brk4FSIiilDQdGkoFSIiilDQdGknlSoielnwjKh7kl86RET0qfIijjpEROyvM2UhMfGSclclKet5Ga+Mg0KVGT8ryN1MRHpkmJmpTnbaQmPjJMSsSkfGioi48MkxIxKe/bSPz7zjApEZPyvo3Ev+/MkhItKe/bSPz3IqOkRErK+zYS/6oySUqUpLxvI/GvKoOkREjK+zYS/6oySEqEpLxvI/GvKoOkREjK+zYSj23MkRIdKe/bSDy2MUZKZKQ815Ka2MYYKZGR8r6NxLuTKVKiIuV9GqmJbYyREhkp79tIvD0ZIyUyUt63kXh7MkZKZKS8byPx9mSMlMhIed9G4u3JGCmRkfK+jcTbkzFSIiPlfRqpiUvMkRIdKe/TSE1cYpCUCEl5IKmJSwySEiEp97ALmgySEiEp740k/uOTQVIiJOW9kdTEJSZJiZKU920k3qBMkhIlKY8kNVGHSVKiJGUOEJ9MkhIlKXOA+GSSlChJ+bCQBJ+DmUySEiUpHxfqog6TpERJynMjqYk6TJISJSnPjaQm6jBJSpSkfFyoizpMkhIlKR8X6qIOk6REScrzLlITdRgkJUJS3htJ/LvKHCnRkfLeSOLfVcZIiYyU90YS/13CGCmRkfLeSOJfVaZIiYqU90YS/6oyREpEpLw3kvhXlRlSoiHlvZHEv6rMkBINKe+7SDzqMEJKJKS87yLxqMMIKZGQ6r6LRH+TFBOkQkGqeyGJdmcxQSoUpLoXknjUKUZIhYRU90YSbc9iglQoSHVvJNH2LAZIhYBU90YSbc9iflToR3UvJNH2LMZHhXxU910k2p7F+KiQj+peR+JRp5gfFfpR3YeReNQp5keFflT3ZSTeoIyPCvmoputIxfiokI9quo5UTI8K9ajG60jF+KiQj2q6jlSMjwr5qKbrSMX4qJCP6j6MxBuU8VEhH9V9GIk3KOOjQj6qx4Ik+BzMYnxUyEe1hpHfxfiokI9KhpHfxfiokI9KhpHfxfiokI9KhpHfxfiokI9KhpHfxfiokI9KhpHfxfiokI9KhpHfxfSoUI9KhpHfxfSoUI9KhpHfxfSoUI9KhpHfxfSoUI9KhpHfxfSoUI9Kh5HfxfSoUI9Kh5HfxfCoEI9Kh5HfxfCoEI9Kh5HfxfCoEI9Kh5Hfxeyo0I5Kh5HfxeiokI5Kp5Hfxeyo0I5Kh5Hfxeyo0I5Kh5Hfxeyo0I5Kh5HfxeiokI7KhpHfxeSoUI7KhpHfxeSoUI7KppHfxeiokI7KppHfxeyo0I7KhqFMxeiokI7KhpHfxeSoUI7KhpHfxeSoUI7KppHfxeiokI7KhpHfxeiokI7KhpHfxeiokI7Kh5HfxeSoUI7Kh5HfxeSoUI7qcSAJPgezGB0V0lH5MPK7GB0V0lH5MPK7GB0V0lH5MPK7GB0V0lH5MPK7GB0V0lH5MPK7GB0V0lH5MPK7GB0V0lH5cHapGB0V0lHFcHapGB0V0lHFcHapGB0V0lHFcHapGB0V0lHFcHapGB0V0lHFcHapGB0V0lHFMPK7GB0V0lHFMPK7GB0V0lHFMPK7GB0V0lHFMPK7mBwVylHFMPK7mBwVylHtaeR3MToqpKPaw8jvYnRUSEe1h5HfxeiokI5qDyO/i9FRIR3VHkZ+F5OjQjmqPYz8LgZHhXBUexr5XUyOCuWo9jTyuxgdFdJR7eGmcTE6KqSj2sPI72JyVChHlcO8xWJyVChHldO8xWJ0VEhHlcO8xWJ0VEhHlcO8xWJ0VEhHlcPI72JyVChHlcPI72JyVChH9TiQhPOow+iokI4qh5HfxeiokI4qhxucxeiokI4qhxucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiokI6qhhucxeiogI7k8+lvcN7FvyW+P/wt0d/gvIuvEgtLnL8bxX+x/mkK1ni35/eHvzX6kd938VVCsUQ/8vsuvkoYlhhGft/VVw3HGv3I77v4KhFYoh/5fRdfJTaWOEMa2BX6u/gqkVjimdEQu/nP+m7Q7w9vjXv1KHkNYkffH/7W6I8u3cVXCezQ1R9duouvEtigqz+6dBdfJbBB13B06a6+amCHruHo0l191cAOXf3Rpbv4KoEduvqjS3fxVQI7dPVHl+7iqwR26BqOLt3VVw3sUOmPLt1FLCHYoNIfXbqLrxLYoHJ+hBb/nhA9+v7wt4a26fEuvkpgh57LR/w54rv6qoEdKn0CvYuvEtigDwbJphcW7+qrBnao9An0Lr5KYIdKn0Dv4qsEdqj0CfQuvkpgg2qfQO8illBsUO0T6F18lcAG1T6B3sVXCexP7RPoXXyVwP7UPoHexVcJbE/tE+hdfJXA9tQ+gd7FVwnsTu0T6F18lcDu1D6B3sVXCexO7RPoXXyVwO60KYESPvr+8LfElEAJH31/+FtiTKCEj74//K0xJVCiR98f/paYEijRo+8Pf0uMCZTw0feHvzWmBEr46PvD3xJTAiV69P3hb4kpgRI9+v7wt8SYQAkffX94a/iYQIkffX/4W2NKoMSPvj/8LTElUMJH3x/+lpgSKOGj7w9/S4wJlPjR94e/NcYESgDp+8PfGlMCJYD0/eFviSmBEkD6/vC3xJRACSB9f/hbYkygRJC+P7w1YkqgRJC+P/wtMSVQIkjfH/6WGBMoIaTvD39rTAmUENL3h78lxgRKDOn7w98aUwIlhvT94W+Jk0DpfcW7+qqBHRpTAiWI9P3hb4kpgRJE+v7wt8SUQAkifX94SwxT7O4iltjYoMMUu7v4KoENOkyxu4uvEtifwxS7u/gqgf05TLG7i68S2J7DFLu7+CqB7TlMsbuLrxLYncMUu7v4KoHdOUyxu4uvEtidwxS7u/gqgd05TLG7i1gisTuHKXZ38VUCuzPHBEoE6fvD3xpTAiWC9P3hb4kpgRJB+v7wt8SYQAkhfX/4W2NKoESQvj/8LTElUCJI3x/+lpgSKBGk7w9/S4wJlBDS94e3Ro0JlBjS94e/NaYESgzp+8PfElMCJYb0/eFviSmBEkP6/vC3xJhACSJ9f/hbY0ygRJG+P/ytMSVQokjfH/6WmBIoUaTvD39LTAmUKNL3h78lxgRKGOn7w1NjfYYEuhgjLWSk9RkS6GKMtJCR1mGkLWxs0V191RCsoUOKXcyRFjrSOkPstv4X8c8KS5AOXehI6zgSD8KLMdJCRlqHkZogvJgjLXSk9emveNzFV4mNJZ6foZuee7yrrxqJNforHnfxVQI7dPVXPO4ilkBGWqu/4nEXXyWwQ1d/xeMuvkpgg67+isddfJXA/lz9FY+7+CqB/bn6Kx538VUC+3P1Vzzu4qsEtufqr3jcxVcJbM/VX/G4i68S2J2rv+JxF18lsDulv+JxF7EEGtKS/orHXXyVwO6U/orHXXyVwO6U/orHXXyVwO4UG4LwYoS0kJDWvYFEfzkvRkgLCWmdG0g8CC8mSAsFaZ0bSE0QXoyQFhLSOleQeBBejJAWEtI6V5B4EF6MkBYS0tJPH4QXI6SFhLQeEOqC8GKGtNCQlsoQhBdDpIWItLQ/BnoXXyWwQ7U/BnoXXyWwQbU/BnoXXyWwQXU4BnpXXzWwQ3U4BnpXXzWwQ7U/BnoXXyWwQ7U/BnoXXyWwQ60/BnoXsQQy0rLhGOhdfdXADrX+GOhdfJXABrX+GOhdfJXABjWbgjBzpIWOtM4Auy4IM0da6EjLYgjCzJEWOtKyfojyXXyVwAY9t5C6IMwgaSEkrWGC3V18lcAOPY606anYu4o10JHWMMHuLr5KYIcOE+zu4qsEdugwwe4uvkpghw4T7O7iqwQ26DDB7i6+SmB/DhPs7uKrBPbnMMHuLr5KYH8OE+zu4qsEtucwwe4uvkpgew4T7O4ilkBEWsMEu7v4KoHdOUywu4uvEtidwwS7u/gqgd05TLC7i68S2J3DBLu7+CqB3XkIqQvCjJAWEtK695D4L2dGSAsJad0RdrzDGSEtJKR17yE1QZgZ0kJDWvciEm9xZkgLDWnde0i8xZkhLTSk9YhQF4SZIS00pLV1CsIMkRYi0to2BWGmSAsVae1+ys1dfJXADt39lJu7+CqBDbr7KTd38VUCG3QPU27u6qsGdugeptzc1VcN7NDsp9zcRSyBjrSyn3JzF18lsEOzn3JzF18lsENzmHJzV181sEOzn3JzF18lsEGzn3JzF18lsEHvTaQmxDJHWuhIK6cEyhxpoSOtHBMog6SFkLRySqDMkRY60jqOtIMnUOZICx1p1ZRAmSMtdKRVUwJljrTQkVZNCZQ50kJHWjUlUMZICxlp1ZRAmSItVKRVUwJlirRQkVZNCZQp0kJFWjUlUKZICxVp1ZRAGSItRCT5DAlUGCIJIpJ8hgQqDJEEEUk+QwIVZkiChiSfIYEKIyRBQpLPkECFEZIgIclnSKDCCEmQkOQzJVBhhCRISPIZEqgwQhIkJPkMCVSYIAkKknymBCqMkAQJSdaQQIURkiAhyRoSqDBCEiQkWUMCFUZIgoQka0qgwgxJ0JBkTQlUGCIJIpKsIYEKQyRBRJI1JFBhiCSISLKGBCoMkQQRSdaUQIUpkqAiyZoSqDBGEmQkkSGBCmMkQUYSGRKoMEYSZCSRIYEKYyRBRhKZEqgwRxJ0JJEhgQpjJEFGEhkSqDBGEmQkuTeR+FasMEcSdCR5UKhLscIcSdCRRLLfihXmSIKOJMeReBAW5kiCjiRnlF0ThIVBkiAkifazmO7iqwR26HGkvWkQFuZIgo4k2s9iuouvEtih2s9iuouvEtih2s9iuouvEtih2s9iuouvEtig2s9iuouvEtif2s9iuouvEtif2s9iuouvEtif1s9iuotYAhVJrJ/FdBdfJbA9rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7rZ/FdBdfJbA7fZjFdFexBgqSeD+L6S6+SmB7ej+L6S6+SmB7+oDwwgRJUJDEB4QXJkiCgiQ+ILwwQRIUJPEJ4YURkiAhiU8IL8yQBA1JfEB4YYYkaEjiA8ILMyRBQ5IYEF6YIQkakhxDSuNZhyGSICLJQaQuPTJFElQkuTeReJMzRRJUJDmKlN78o7AWRUaSmBIoYyRBRpIzzY4/h3xXXzWwRQ8j8eeQ7+qrBrZo9O/I3cVXCWzR40hdfGSOJOhIchypiY/MkQQdSY4j8SeV7+qrBvbogaSdPIIySRKUJNlTBGWQJAhJcm4jlfDtBAZJgpAkDwt1MZZBkiAkycNCXYxlkCQISfKwUBdjGSQJQpI8KtTFWOZIgo4kDwp1MZYxkiAjyb2OxH8OM0YSZCS515H4z2HGSIKMJIeRmhjLGEmQkeTeRuI/QpkiCSqSHEVqYixTJEFFkqNITYxliiSoSHIuIzUxliGSICLJQaQmxjJEEkQkOYjUxFhmSIKGJMeQmhjLDEnQkKQ+Q4xlhCRISHKvIjUxlhmSoCHJvYvE25MZkqAhyb2LxNuTGZKgIcm9i8TbkxmSoCHJvYrE25MZkqAhyb2JxNuTGZKgIckxpC7GMkQSRCQ5iNTFWKZIgookR5FK/3P7t/PVGqxDkZH0M2yCKmMkRUbSw0hl/7n/849hDdKhio6kx5HK//P4J/jbWRkkKUKSHkiqaP5/kB5VlCQ9ksRjvTJJUpQkPZJUu/lHIU2qSEn66SfS38VXicASw0T6u/qqsbFGP5H+Lr5KJJboJ9LfxVcJbNEjSU0kV0ZJipSkh5KaSK7MkhQtSe+LSPSHjzJLUrQkvS8i0R8+yihJkZL0TLVr4rQySlKkJH1gSHbROK3MkhQtSR8ZauK0MktStCQ9ltTEaWWYpIhJuoaRDcosSdGSdA0jG5RRkiIlqQwjG5RRkiIlqQwjG5RRkiIlqQwjG5RRkiIlqQwjG5RJkqIkqQwjG5RJkqIkqQwjG5RJkqIkqQwjG5RBkiIkqQwjG5Q5kqIjqQwjG5Q5kqIjqQwjG5Q5kqIjqQ4jG5QxkiIjqQ4jG5QxkiIj6X0SiScNpkiKiqT3NhLvTqZIioqk9zYSj9PKGEmRkfReR+LtyRhJkZH0Xkfi7ckYSZGR9N5G4u3JGEmRkfReRuLtyRhJkZH0PonE25MxkiIj6X0SicdpZY6k6Eh630TicVoZJClCkh5IauK0MklSlCS9jyLxJmeSpChJeiSpi9OMkhQpSQ8ldXGaWZKiJemxpC5OM0xSxCS1YWaDMkxSxCQ9mNTFaaZJipqk9z4S/5XENElRk/Q+i9TEaaZJipqk910k/qVnmqSoSXo0qYnTTJMUNUmPJnVxmnGSIifp4aQuTjNPUvQk9WFogzJPUvQkPZ7UxGnGSYqcpIeTujjNOEmRk/TBIUk+P1eZJyl6kvowtEGZJyl6ksYwtEGZJyl6ksYwtEEZJylyksYwtEGZJilqksYwtEGZJilqksYwtEEZJilikh5M2us/z3+f978M1qCoSXrfRuI//xgmKWKS3jtJ/GcXsyRFS9I4/bn437MYJiliksZwYlmZJSlaku7hxLIyS1K0JN3DiWVllKRISbqHE8vKJElRkvTcScrm762MkhQpSc+dpNSmButQpCTdw4ERZZSkSEm6hwMjyihJkZJ0DwdGlFGSIiXpHg6MKKMkRUrSPRwYUUZJipSkDwxJGv9PwixJ0ZI0p916ZZikiEl6ZtslP7SsTJMUNUmPJjV/RWGapKhJemfb8a8r0yRFTdIcjiwr0yRFTdIcjiwr0yRFTdIcjiwr0yRFTdIz2i6j+U/COhQ5SQ8ndX/NYZ6k6El6Pan5aw4DJUVQ0gtK/MvGPEnRk/R4UhPrmScpepIeT2oiOfMkRU/S40ldJGegpAhKekCpieQMlBRBSQ8oNZGcgZIiKGkNl+aUeZKiJ2lNl+aUeZKiJ2kNl+aUcZIiJ9nn/AzlZ4WNeZKhJ9lnuDRnjJMMOck+w6U5Y5pkqEn2GS7NGcMkQ0yyz3BpzhgmGWKSfYZLc8YsydCS7DNcmjNmSYaWZMeSmihszJIMLcmOJfEobMySDC3JjiXxKGzMkgwtyc4DSU0UNmZJhpZkazizbIySDCnJ1nBm2RglGVKSreHMsjFKMqQkW8OZZWOSZChJdiSpicLGJMlQkuxxoS4KG6MkQ0qyO9uO/ugyJkmGkmR3th2NwsYkyVCS7M62o1HYmCQZSpLd2Xb0t7MxSTKUJDuXkngUNiZJhpJk532kJgoboyRDSrJDSU0UNmZJhpZkZ7pdE4WNYZIhJpkMu/XGMMkQk0yG3XpjmGSISSbDbr0xTDLEJJNht94YJhliksmwW28Mkwwxyc5wuyYKG9MkQ02yo0lNFDbGSYacZIeTmihszJMMPcl02K035kmGnmQ6HBgxxkmGnGSHk3gUNsZJhpxkh5OaKGzMkww9yY4n8ShszJMMPcmOJ/EobMyTDD3JdLg2Z8yTDD3JbLo2Z8yTDD3JbLg2Z4yTDDnJziNJyc8sG+MkQ04yG84sG+MkQ04yG67NGdMkQ00yG67NGcMkQ0wyG67NGbMkQ0syG67NGbMkQ0syG67NGaMkQ0qyQ0ldFGaWZGhJ5sOZZWOUZEhJ5sOZZWOUZEhJ5jJFYWZJhpZkx5KaKMwoyZCS7FBSE4WZJBlKkh1JaqIwkyRDSbIjSU0UZpJkKEn2sFAbhZkkGUqSXUlqojCTJENJMh8OjBiTJENJshgOjBiTJENJshgOjBiTJENJshgOjBiTJENJshgOjBiTJENJsrApCjNKMqQki+mND2OUZEhJdubbdVGYWZKhJdmxpCYKM0sytCS78+3415VRkiEl2Z1vx7+ujJIMKcnueDv+dWWUZEhJdsfb8a8JoyRDSrJzK6mLwsySDC3JzhtJXRRmlmRoSXauJXVRmFmSoSXZnW/Hv2zMkgwtyY4lNVGYWZKhJdmxpCYKM0sytCQ7ltRFYYZJhphkB5OaKMwwyRCT7NxLaqIwsyRDS7I73o43OaMkQ0qycy+pi8KMkgwpyXI4s2yMkgwpyfL8DOXnjY1ZkqEl2SNDXRRmlmRoSfbIUBeFmSUZWpI9MtRFYWZJhpZkDwx1UZhRkiEl2eNCXRRmkmQoSfawUBeFGSQZQpIdSOqiMJMkQ0myI0lNFGaSZChJdiSpicJMkgwlycqmKMwkyVCSrIYzy8YkyVCSrIYzy8YkyVCSrIYzy8YkyVCSrIYzy8YgyRCS7GGhNgozSTKUJL+SxKOwM0lylCT/DK98OJMkR0nyz/DKhzNJcpQk/wyvfDiTJEdJ8jvgjv52diZJjpLk51oSj8LOJMlRkvwMuGuisDNKcqQk/0yvfDijJEdK8vNIUhOFnVmSoyX5HXFHv67OLMnRkvxOuKNfV2eU5EhJvoZ35pxRkiMl+RremXNGSY6U5Gt4Z84ZJTlSkp8Bd00UdmZJjpbkd8Adj8LOLMnRkvxOuONR2JklOVqS3xF3/MvGLMnRkvxYEo/CzizJ0ZJ8DWeWnVmSoyW5TGeWnWGSIya5DGeWnWGSIya5DGeWnVmSoyX5nXDHm5xRkiMl+bmW1ERhZ5TkSEl+J9zxLwqjJEdK8jPhrvhZYWeW5GhJ/shQE4WdWZKjJbkM1+acWZKjJbkM1+acWZKjJbkO1+acUZIjJbkO1+acSZKjJLkO1+acQZIjJPmBpCYKO5MkR0nyI0k8CjuTJEdJ8iNJPAo7kyRHSXKNIQo7kyRHSXIdHppzJkmOkuQ6PDTnTJK+PvwtMTw0939nZ7vkRo6j63uZ3x0dCfB77+Bcw8bGhlwl2zotl2pVKnv6bOy9n1CSfJNEIjn0/tM4p1HKFJIE8QAvnEaSnCRJzg4GzTkNJDkJktyKhY5CYaeRJCdJkisk6SAU1kiSkyTJ2YHKstNIkpMkydmByrLTSJKTJMnZgcqy00iSkyTJFYk7fXfWSJKTJMnlrqSDUFgjSU6SJGfjKBTWUJKTKMnZkcqy01CSkyjJ5TFJR6GwxpKcZEluJHLnNJbkJEtyI5E7p6EkJ1GSG4ncOQ0lOYmS3EjkzmkoyUmU5EYid05DSU6iJOf8KBTWWJKTLMm5kcKI01iSkyzJuZHCiNNYkpMsyWWWdBAKayzJSZbkisqd/rJpLMlJluQySzoIhTWW5CRLckORO6fBJCdhkhuJ3DkNJjkJk1wWuTsIhTWW5CRLcn7QNuc0lOQkSnK5K+koFNZQkpMoyWWUdBAKayjJSZTkcltSIj0U1liSkyzJ+UHbnNNYkpMsyYVB25zTWJKTLMmFQduc01iSkyzJhUHbnNNQkpMoyYVB25zTSJKTJMmFQduc00CSkyDJhVHbnNNIkpMkyYVB25zTSJKTJMmFQduc00iSkyTJhVHbnNNIkpMkyYVB25zTSJKTJMnFQduc00iSkyTJxUHbnNNIkpMkycVB25zTQJKTIMnFUduc00iSkyTJxVHbnNNIkpMkycVB25zTSJKTJMnFQduc00iSkyTJxUHbnNNIkpMkycVB25zTSJKTJMnFQduc00iSkyTJpVHbnNNQkpMoyQ1F7pyGkpxESS6N2uacxpKcZEkuDdrmnMaSnGRJLg3a5pyGkpxESS4N2uachpKcREkuDdrmnIaSnERJLg3a5pyGkpxESS6N2uacxpKcZEkujdrmnMaSnGRJfhm1zXmNJXnJkvwyaJvzGkvykiX5ZdA25zWW5CVL8sugbc5rLMlLluSXUduc12CSlzDJL4O2Oa/BJC9hkl8GbXNeY0lesiS/DNrmvIaSvERJfhm1zXkNJXmJkvwyaJvzGkryEiX53JaUWA2FvcaSvGRJngZtc15jSV6yJE+DtjmvsSQvWZKnQduc11iSlyzJ06BtzmsoyUuU5GnQNuc1kuQlSfI0aJvzGkjyEiR5GrXNeY0keUmSPA3a5rxGkrwkSZ4GbXNeI0lekiTPo7Y5r5EkL0mS50HbnNdIkpckyfOgbc5rJMlLkuR50DbnNZLkJUnyPGib8xpI8hIkeR61zXmNJHlJkjyP2ua8RpK8JEmeB21zXiNJXpIkz4O2Oa+RJC9JkudB25zXSJKXJMmbQduc10iSlyTJm0HbnNdIkpckyZtR25zXUJKXKMmbUduc11CSlyjJm1HbnNdYkpcsyY9E7rzGkrxkSX4kcuc1lOQlSvIjkTuvoSQvUZIfidx5DSV5iZL8SOTOayjJS5Tk7ahtzmssyUuW5O2obc5rLMlLluTtqG3OayzJS5bkRyJ3XmNJXrIkbwdtc15jSV6yJG8HbXNeY0lesiRvR21zXoNJXsIkbwdtc16DSV7CJG8HbXNeY0lesiRvB21zXkNJXqIk70Ztc15DSV6iJO8GbXNeQ0leoiSf25KS0UNhjSV5yZK8G7TNeY0lecmSvBu0zXmNJXnJkrwbtM15jSV5yZK8G7TNeQ0leYmSvBu0zXmNJHlJkrwbtM15DSR5CZK8G7XNeY0keUmSvB+0zXmNJHlJkrwftM15jSR5SZK8H7XNeY0keUmSvB+0zXmNJHlJkrwftM15jSR5SZK8H7TNeY0keUmSvB+0zXkNJHkJkrwftc15jSR5SZK8H7XNeY0keUmSvB+0zXmNJHlJknwYtM15jSR5SZJ8GLTNeY0keUmSfBi0zXmNJHlJknwYtM15jSR5SZJ8GLXNeQ0leYmSfBi1zXkNJXmJknwYtc15jSV5yZJ8GLTNeY0lecmSfBi0zXkNJXmJknwYtM15DSV5iZJ8HLTNeQ0leYmSfBy0zXkNJXmJknwctc15jSV5yZJ8HLXNeY0lecmSfBy1zXmNJXnJknwctM15jSV5yZJ8HLTNeY0lecmSfBy0zXmNJXnJknwctc15DSZ5CZN8HLTNeQ0meQmTfBq0zXmNJXnJknwatM15DSV5iZJ8GrXNeQ0leYmSfBq0zXkNJXmJknxuS0pWD4U1luQlS/Jp0DbnNZbkJUvyadA25zWW5CVL8mnQNuc1luQlS/Jp0DbnNZTkJUryadA25zWS5CVJCsugbS5oIClIkBRKU5L6vgcNJAUJkkJpSlLf96CBpCBBUlgGIWjQQFKQICksgxA0aBwpSI4UlkEIGjSOFCRHCssgBA0aRwqSI4VlkAUNGkcKkiOFZZAFDRpGChIjhWWQBQ0aRgoSIwUaZEGDRpGCpEiBBlnQoFGkIClSKB1JetgWNIwUJEYKNADxQcNIQWKkQAMQHzSMFCRGCjQA8UHDSEFipEADEB80jBQkRgo0APFBo0hBUqSQKdJBuBQ0jBQkRgoZIx2ES0HjSEFypMCDaXNBw0hBYqRQGpJ0B9UwUpAYKZSGJH351DBSkBgplIYkPVwKGkcKkiOFzJH0cCloHClIjhRKQ5LuoBpGChIjhaxtp4dLQaNIQVKkwINa0KBRpCApUuBcC+rUUCdoGClIjBQyRjoYhh00jhQkRwpm1DIXNJAUJEgKGSQdTLIOGkkKkiSFrG53MKQjaCQpSJIUMkk6GNIRNJIUJEkKmSQlr/8uGkkKkiSFlQtxCn9Y+ycHK21oXipRUshtSUkf0xE0lhQkSworGeKUDmxofiphUljRkFmWP3z6c1l2NjQ/lTQprGzILHTwPTQ/lTgprGzILPyHW/6MTpjQaFKQNCmsaMgsRjeheamESWElQ2axfzj607D0Dg0mBQmTwoqGzOL0p6HRpCBpUljZkFm8/qtoOClInBRWOGSWcPA9NC+VPCmscMgsB16q8aQgeVJY6ZBZDrxUA0pBAqWw4iFDy4ENzUslUQorHzKkV+cHDSkFiZTCyocM6WVNQUNKQSKlsAKiw9VDY0pBMqWwAqIQ1ON80JBSkEgprIDIkDmwobmpZErB2dHioUGlIKFScG7w1mpQKUioFJwfvS0aVQqSKoWVERmyKs8JGlYKEisFl73U6beiOanESsFlJ/UHv4rmpBIrBZ+dVJesDxpXCpIrhZUSGdK1PoMGloIES2GlRIZ0kaSggaUgwVLIYCnSH4H/ND5KG5qXSrIUVk5kWO9QDxpaChIthRUUGaY/vP3TRuliGlsKki2FlRQZ5gMbmptKuBRWUmTTH57/jLQzoXmpZEthBUWGdR4dNLYUJFsKKykybA9+Fs1NJVwKKyoyfBAha3QpSLoUAo0WMQ0vBYmXwgqLDB9EhBpfCpIvhTAoEg0aXwqSL4WQvfTgrdX4UpB8KYTspVH/WTS+FCRfCiF76cFbq/GlIPlSWGmRMQf7ggaYggRMYcVFxhxs1xphCpIwhZUXGXOwXWuIKUjEFFZgZMzB66IxpiAZU1iJkTH2D+//tDJ/pDGmIBlTWIGRMQdvi8aYgmRMYQVGxhzskxpjCpIxhRUYHW5QGmMKkjGFlRgZc+DqGmQKEjKFFRkZc7BBaZQpSMoUYnbTA1fXMFOQmCnkQUpH0ZyGmYLETGGFRsYebFAaZwqSM4WVGhl78LpooClI0BRWbHS4qmukKUjSFFZsZOzBK6eRpiBJU1i5kbFGfV000hQkaQorNjL2IHWikaYgSVNYudHh5qKhpiBRU8io6WBj0FBTkKgprODIWHfwq2heKllTWMmRsQdvvgabgoRNIWUvDQc2NC+VtCkuy+DAEDXcFCVuigsNNrmo8aYoeVNceLBBRQ04RQmc4pK9NKqxWNSIU5TEKS7ZTdPB91DcNErkFFeAZNzyh1/+3H8NxUujRE5x8cfJl6ghpyiRU1wBknGkvbNRQ05RIqe4xONdMmrIKUrkFFeAZBwf+Ibio1Eyp7gSJOOMbkODTlFCp0g0OJFGjTpFSZ0i8eBEGjXqFCV1ijTa8aOGnaLETnGFSMbp0D5q3ClK7hQp+6jT3xUNPEUJnuKKkY4ij6iRpyjJU6TspV51MY08RUme4oqRjNOXwaiRpyjJU6TspnrwEjXyFCV5ipzdVA9eooaeokRPkWlwqo0ae4qSPUXmwak2avApSvgUV5J0cKqNGnuKkj3FlSQZr8dQUYNPUcKnyKNDftToU5T0KfLokB81/BQlfoo8OORHDT9FiZ/iypKM18PBqOGnKPFTXFmS8XooFzX8FCV+iiNBvKjRpyjpU1xRkvH6ASxq9ClK+hRXlGT8wRqm0aco6VNcUZLx+gksavQpSvoUTfZSPdcQNfoUJX2KK0oyPuj7k0afoqRPcUVJxh8sQBp9ipI+xRUlGX+wAGn0KUr6FDN9CgdvrUafoqRPMdOncODqGn2Kkj7FTJ/Cgatr+ClK/BQLftLZUdT4U5T8KWb+FA5iD40/Rcmf4gqTjk6kUeNPUfKnaO2ATkaNP0XJn6J1AzoZNf4UJX+KhT/pZDFq/ClK/hQLf9KDWw0/RYmfYsZPOqOIGn2Kkj7FTJ8OvUPzUkmfYqZPB2QxavQpSvoUHQ2oYNToU5T0KToeUMGo4aco8VPM+OmACkYNP0WJn2LGTwdUMGr4KUr8FDN+Cgc7g8afouRPMc9aSknf8zX+FCV/innY0rLob77Gn6LkTzEPW1p0WBI1ABUlgIorTeLlIH7RAFSUACquNIkXo9vQAFSUACquNIkXe2BD81MJoGIGUOFgx9YAVJQAKvrhaqoBqCgBVMwAKhycwjQAFSWAit6NVmQNQEUJoGKeuHS0ImsAKkoAFX0YrcgagYqSQMVMoA4yFhqAihJAxQygDhZ1jT9FyZ9i5k8Hi7qGn6LETzEMt3wNP0WJn2LGT0eLuoafosRPcYVJJgT9ZdH4U5T8KWb+dLQxaPwpSv4UM3862hg0/hQlf4qZPx1tDBp/ipI/xcyfjjYGjT9FyZ9i5k/hIETW+FOU/CmuMOlw8dD4U5T8KWb+FA5ShBp/ipI/xZUmHZSLRI0/RcmfYuZPB8nwqPGnKPlTzPwpHuxxGn+Kkj/FzJ8OkoQafooSP8WMn47eFg0/RYmfYsZPeqlH1OhTlPQpZvp0lM/S6FOU9CmuKMnEg7OPRp+ipE9xRUn8LNNQfxXNSSV9ilkyjw9+WY0+RUmf4oqSmA9ytxp9ipI+xSyZxwfnJ40+RUmfYhpVQkcNP0WJn2LWzDuodo0afooSP8UsmndQ7Ro1/BQlfoorTDLx4Fyr8aco+VNMYbSIafwpSv4Us27eUfSi8aco+VPMM5iOoheNP0XJn1LhT3r0kjT+lCR/Spk/6aFH0vBTkvgpZfykhx5Jo09J0qeU6dNB6JE0+pQkfUqZPh2EHkmjT0nSp7SMqkyThp+SxE9pGVWZJo0/Jcmf0jKqMk0agEoSQKVlVGWaNAKVJIFKmUBFPVuZNAKVJIFKRTxPf+OSRqCSJFCJBlt+0gBUkgAq0WjLTxqAShJApQygDjxd409J8qeU+dMBB0saf0qSP6XMn/TtOmn4KUn8lIb4KWn4KUn8lDJ+inqyIWn8KUn+lIadT0njT0nypzTsfEoaf0qSP6Xc+ZTMH87+GaKIxJLGn5LkTym3PiX7h3N/ukU+U40/JcmfUu59Su4P5/9k2RCcNP6UJH9Kufkp+YPvobmpBFApNz+lcPA9NDeVACrl7qeDsCFpACpJAJVy+9NB2JA0AJUkgEqc/VRPnCSNQCVJoBKPCqOSRqCSJFApE6ioJ06SRqCSJFBp5UkmBlWcIWkIKkkElQwNwpekIagkEVTKCCpG/V40BJUkgkoZQR1UNSUNQSWJoFJGUDFpB6ikEagkCVQyo8x+0ghUkgQqZQKV9AqcpBGoJAlUMqNcVNIIVJIEKpX+Jz2a0wBUkgAqlfYnfY/T+FOS/CmV7qeDaE7jT0nyp1T400E0p/GnJPlTyvwpkf6raPwpSf6USv/TQUSo8ack+VPK/U+JD76H5qWSPyU7SkYljT8lyZ+SHSWjksafkuRPyY6SUUkDUEkCqJQB1IGGXNIIVJIEKtlRMippBCpJApXccDHVCFSSBCplAqVXdyYNQCUJoFIGUEfroAagkgRQaaVJRwGyxp+S5E+p8KeDAFnjT0nyp5T501F0q/GnJPlTcoNkVNLwU5L4KblRMipp+ClJ/JRy+9OBukvS8FOS+Cm5kTh+0vBTkvgp+ZE4ftLwU5L4KWVdvaPoVsNPSeKnlEc0HUW3Gn5KEj+l3P90FN1q+ClJ/JSyst5RdKvhpyTxU8rSekfRrYafksRPKWvrHUW3Gn5KEj+lPKXpKLrV8FOS+Cll/HTQmp80/pQkf0p+uJhqACpJAJUygDqKbjUClSSBSplAHS3IGoFKkkClwKPoViNQSRKolAnUUXSrEagkCVQKo5r9pBGoJAlUygTqILrVAFSSACqFESVNGoBKEkClDKCOolsNQCUJoFIGUEfRrQagkgRQKQwwadL4U5L8KcUBJk0afkoSP6U4wqRJ409J8qcUR5g0afwpSf6UMn86im41/pQkf0pxhEmTBqCSBFApA6ij6FYDUEkCqBSHOVONQCVJoFIc5kw1ApUkgUpxmDPVCFSSBCrl/qcDTY6kEagkCVRKw5ypRqCSJFApDRdTjUAlSaBS6X/So1sNQCUJoFIanvI1AJUkgEorTTqKbjX+lCR/SsP2p6TxpyT5U8r86Si61fhTkvwp5f6ng+hWw09J4qeU25+OolsNPyWJn1Juf0p602LS8FMS+MksK0vSf5VysTfR/mM1sfpoUssSytWdDZI21g1fY6Tl2s4CSwt5JVVrf8vVnQ0jbTwdzi5q7W+5urNhpY1VDHJR+Xe5urPhpA1/vHKUqzsbXtoIxyFUubqzEaSNeBx3lKs7G1HaGCjxlKs7G9JJS/+TVp1VLkoTJJ2UjhFpubgzIX2UjhFpubgzIZ2UBoi0XN3ZkE5KA0Raru5sSCel7KTqdl+u7mxIJ830Sa9ZKVd3NqSTZvqkhy7l6s6GdNLc/aSHHeXqzoZ00tz9pIcd5erOhnTS3P2khx3lqrTB0ktXlGQXNalWru5sSDdlHi0eCn1q/7HaMMdhR7m6syH9lI/3+3JxZ0K6KQ/2+3J1Z0O6ae5+UrtAy8WdCemlmT3p7Zfl6s6G9FI+FuIpF3cmpJPyQIinXN3ZkE66ciS7qAmxclXaMNJJs/aeXlteru5sSCfNU5zI6AuQgp7af6w2zHFdeLm6syGdNGvv6XXh5erOhvTSMsVJTRCWqzsb0kvLGCc1QViu7mxIN83ae3p9erm6syHddCVJdlETUeXqzob00xUl2cXrr4tCn9p/LDZs9lM1tC1XpQ0r/dTmxfQgLlXoU/uP1cZwMVXoU/uP1YY5rrUvV3c2pJ+Oup/K1Z0N6afWjX4XhT61/1htDDJR5erOhvRTO2Ck5erOhvRTe1yvXy7uTEg3tceJqHJxZ0J6qTtORJWL0oSTTuoGiahydWdDOqkbJKLK1Z0N6aRuUK9fru5sSCd1g0RUubqzIZ3UDRBpubqzIZ3UDRBpubqzIZ3UDRBpubqzIZ3U5cX04Eiq0Kf2H6uNQVa/XN3ZkG7qB/X65aq04aWf+uPivXJxZ0K6qR8U75WrOxvSTf2gXr9c3dmQbuqP6/XLxZ0J6aV+UK9fru5sSC/N2nu6EEa5urMhvdQfJ6LKxZ0J6aR+kIgqV3c2pJOuHMnSQd5EQU/tPxYbK0fSJ2CUi9JEkD4aBjKm5erOhnTSFSNZXZK1XN3ZkE5aep8OzgsKeWr/sdpYU1G6rGu5urMhvXTlSJYOTpMKemr/sdo4VosqF3cmpJOuGMnSwZlDIU/tP1Yb61JKB3GpQp7af6w2speqOf1ydWdDemmR3lMpWrkqbUTppitI0gUoysWdCemlK0fSp6yUizsT0knjMBWlkKf2H6sNezippVzcmZA+GgfSEeXqzob00Tiogy5Xdzakk8bspAcHDgU8tf9YbWQnVYlzubqzIZ00Zic9iBkU8NT+Y7GxUiSrq8uWq9JGkk6ahmupAp7af6w2jiWhy8WdCemlaSAJXa7ubEgvzcJ7B5ukAp7af6wm3MjDFPDU/mO14ddf5WBnUcBT+4/VRhg+Ds1Lk/TSPOTpYEVXwFP7j9XE6qR8sDkp4Kn9x2yD8pQnfQkjDTyRBE+0UiSrywaXqzsbJG2s+z3rmxNp6IkkeqKVI1ldNrhc3dkw0oYdvG+koSeS6ImWQUN+ubqz4aSN0QGfNPREEj3RypEs64kG0tATSfREufFJlzIsV3c2orQxQk+koSeS6IlG6Ik09EQSPdEIPZGGnkiiJxqhJ9LQE0n0REP0RBp6IomeaIieSENPJNET0aA7r1zd2ZBOSoNKk3J1Z0M6KQ0qTcrVnQ3ppDSoNClXdzakkxbhPVWHsFzd2ZBOynnD14MX0tATSfREPNrwSUNPJNET8WDDJ408kSRPxKMNnzTyRJI8URbeO1o7NPREEj0RH0uYlos7E9JLC3k6+GU19EQSPREPDvikkSeS5Il4dMAnDT2RRE/EecPXU+mkoSeS6IlMbsjXs1CkoSeS6Ily19PB8Ys09EQSPVFGT0YtuStXdzakl2b0ZHR+Thp6IomeKKMnoyMw0tATSfREGT3pwgDl6s6GdFMzqIEuV3c2pJuaQQ10ubqzIf00oydd5b9c3dmQfprRk9FPPqShJ5LoieygbK9clTYkeiI76M4rV3c2pJ8W9HSwQWnoiSR6otL4dBABaeiJJHoiOxCELld3NqSflsYnPQTSyBNJ8kSl70kPgTTwRBI8UQFPByGQBp5IgicqunsHIZBGnkiSJ7LZS/WTIGnoiSR6ohUkWX2ORLkqbUj2RCPhvXJ1Z0N66Uh4r1zd2ZBeOhLeK1d3NqSXjoT3ytWdDemlK0iy+lyNcnVnQ7qpG5XukcaeSLInWkHSURiloSeS6InK3KeDMEpDTyTRE+XBT0dhlIaeSKInyujpaPHQ0BNJ9ET+eIheubgzIb00oyddhL1c3dmQXprRk144XK7ubEgvzejpKCTU2BNJ9kT+WDiiXNyZkE7qRwlT0tATSfREeeyTOUicaOyJJHsiP2jIL1d3NqSXriDp6GXR0BNJ9ES56+noZdHYE0n2RGF0yNfQE0n0RFl27+CH1cgTSfJEmTwd/bAaeSJJniiTJ32sT7m6syF9NLjRD6uRJ5LkiUrT08HOoqEnkuiJQhjFUBp6IomeaNT0VK7ubEgnHTQ9lYs7E9JJB01P5aI0IcETjZqeytWdDemko6ancnVnQ3ppHLTjl6s7G9JLS9PTgXdo7Ikke6LMno7iDo09kWRPVNjTQdyhsSeS7Ily05M+v6Fc3dmQXprZk9HhJmnsiSR7ojiqNSGNPZFkT5QG/SSkoSeS6InSYIJeubqzId00jdZSDT2RRE+Uhmuphp5IoifK6Onol9XYE0n2RClHpQfJPY09kWRPtIIk9l7r3ypXdzakl2bRPaeWhJOGnkiiJ8qaez4cfA3NSSV7oqy55+OBDc1JJXvilSSxT6oN1uATS/jEK0nioHXVlYs7EyRNrOxJHxhXru5ssLSxsid9YFy5urNhpI0Re2KNPbFkT5xF9w6KXFljTyzZEy+jHZ819sSSPfEy2vFZY08s2RMvox2fNfbEkj3xMtjxWUNPLNET02DHZw09sURPTKMdnzX2xJI9MY12fNbgE0v4xDTa8VmDTyzhE9Nox2cNPrGET0yjHZ81+MQSPjGNdnzW4BNL+MQrSbL6eMVydWdDeimNDk+swSeW8IkzfDqoDGUNPrGET8yDHZ819sSSPTGPdnzW2BNL9sR56JM+k7Bc3dmQbprh08FLq7EnluyJeVBswhp6YomemEfFJqyxJ5bsiVeQZPXZm+XqzoZ0Uh6o7JarOxvSSXmgsluu7mxIJ+WBym65urMhnTT3PR2UJLAGn1jCJ85Tnw7yYazBJ5bwibPk3tHWosEnlvCJzchLNfbEkj1xVtw72Fo09MQSPXGe+XS0tWjoiSV64qy4d7S1aOiJJXpiM2ohZQ09sURPbEYtpKyhJ5boic2ohZQ19MQSPbEdtZCyhp5YoifOmnsHKUbW0BNL9MQrR7L6xNxydWdDeulo5lO5urMh3dQOWkhZI08syRPbUQspa+iJJXrijJ6OXnyNPbFkT5zZ0+HPormpZE+8giRrdT7BGntiyZ44dz0d7E8aemKJnjh3PR3tTxp6YomeeOVI1urZY9bQE0v0xG7Um8caemKJntiZ0f6koSeW6ImdHe1PGnpiiZ64tD0d7AsaemKJntjlPV9P3LKGnliiJ85tT3rZC2voiSV6YncsX1ou7kxIJ3XH8qXl4s6EdFI/kC8tV6UNCZ7YD+RLy9WdDemkK0Y6UlpgjTyxJE/sh6cnjTyxJE/sh6cnjTyxJE/sh6cnDT2xRE/sh6cnDT2xRE+c0ZPVc52soSeW6ImH6Ik19MQSPXGe+HSgksAae2LJnjiMTk8aemKJnjgMT08ae2LJnjizJ10lgTX2xJI9cWFP+s6ioSeW6Imz3N7RzqKhJ5boiXPTk9XTpayhJ5boiTN6Iq+ughp5YkmeOIRBVRVr5IkleeIVIx1VVbFGnliSJ85NT/Ygx6ihJ5boieOoIoo19sSSPXEcVUSxxp5YsieOOSw9yHVq7Ikle+Iy8ElTYywXdyakl8bhfq+hJ5boieNwv9fQE0v0xEVvT99oNfLEkjxxkdvTN1oNPLEET5zV9o42Wg08sQRPnNX2jjZaDTyxBE+cm57cQUpNI08syROnUUEUa+SJJXniNCqIYg09sURPnEYFUayhJ5boidOoIIo19MQSPXFGT+4gi6ShJ5boiXPbkzs4S2roiSV64hUkWXdw8NHYE0v2xCtIsu7gxKGxJ5bsidMIkLLGnliyJzMS3DMaejISPZlltOEbjT0ZyZ5MnvdkdV5jNPZkJHsyWXLP6nTTaOzJSPZklsEonXJ1Z8NKG4OKKKOhJyPRk1lGFVFGQ09GoieT5z05r20tRiNPRpIns2Qn1Y9wRiNPRpIns4yc1GjoyUj0ZMq4J30RMxp7MpI9GaLBNmk09mQkezI0SpcajT0ZyZ5MZk/6kdZo6MlI9GQKelJ3WqORJyPJkynkSd1pjQaejARPpnQ96Tut0cCTkeDJlK4nfac1GngyEjwZioMjrdHAk5HgyRTBPX2nNRp4MhI8mSy4d7DTGo08GUmeTCZPBzut0ciTkeTJZPJ0sNMajTwZSZ7MypGs04+0RkNPRqInwyOMbzT2ZCR7Mpk9HRxpjcaejGRPZgVJRzuchp6MRE+GR33ORkNPRqInk/ue9COt0ciTkeTJ8CBZajTwZCR4MmaULDUaeDISPJmVIlmnH2mNBp6MBE9mpUjW6edAo4EnI8GTyV1P+rHYaODJSPBkVox0dCw2GnkykjyZ3PR0cCw2GnkykjwZk6NS/ShpNPJkJHkyZsRHjUaejCRPxoz4qNHIk5HkyeSmJ6+ffIxGnowkT6Y0PR2sgxp5MpI8mTLt6WCz1siTkeTJ5GlPBzutBp6MBE+m9DzpO63GnYzkTia3PB3ttBp4MhI8mdLydLDTauDJSPBk7ECrvFzd2ZBeakd81GjgyUjwZOyIjxoNPBkJnowd8VGjkScjyZNxIz5qNPJkJHkyuenpIErXwJOR4MmsFMl6/VhsNPBkJHgyboRHjQaejARPxg3wqNG4k5HcybgRHjUadzKSO5kst3d0lNS4k5HcyWTudHSU1MCTkeDJlJ6ng7dFI09GkifjRju+Rp6MJE/GD3d8jTwZSZ6MHzmpBp6MBE8mgyev512MBp6MBE/GD51UA09GgifjR06qcScjuZPxQyfVuJOR3Mn444Fk5eLOhPRRPxhIVq7ubEgfXRmS9Xomy2jYyUjsZLLantczWUbDTkZiJ7NCJOsPEg0adzKSO5kVIh3pHhuNOxnJncxKkY50j40GnowETyaY48Fo5erOhvTSYI8Ho5WrOxvSTYM7HoxWru5sSDddOdLBYLRydWdD+mlGT/pgtHJ1Z0P6aUFPB3G6hp6MRE9m5UiHcbqGnoxETyZmPz04F2voyUj0ZOJI2cRo6MlI9GRy25M+GK1c3dmQfhpHovpGY09GsicTRzrQRmNPRrInk9mTPhitXN3ZkH6a2ZM+EKhc3dmQfprhk47ijAafjIRPJo4GlBgNPhkJn0wZ9aRrihgNPhkJn0xaRkcfDT4ZCZ9MGnSQGo09GcmeTBrIRBkNPRmJnkwayUQZDT0ZiZ5MGslEGQ09GYmeTFbc0wejlas7G9JJ86ino6OPhp6MRE8mK+7pg9HK1Z0N6aVpeHzS0JOR6Mmk4fFJQ09Goie7jI5PVmNPVrInmzX3vJ6Lshp7spI92WVUuGc19mQle7LLaDG1Gnuykj3ZzJ7UwWjl4s6ElSbcYB20Gnuykj3ZZZAvtRp6shI92WWUL7Uae7KSPdlldHyyGnuykj3ZZXB8shp6shI9WRodn6yGnqxET5ayk+rJTquhJyvRk6V8ftIzhFZDT1aiJ7uCJBv0zJzV2JOV7MmuJMkGPdlgNfhkJXyyedxT0M+CVqNPVtInu6IkG/STi9Xok5X0yea2p6CfXKxGn6ykTzbTp6CfXKxGn6ykT3ZFSTboUaXV6JOV9Mlmzb1wsBBq9MlK+mRXlKRr2VuNPVnJnuwKkmw48HSNPVnJnmxmT+HA0zX2ZCV7sitIsvHA0zX2ZCV7sitIsvHA0zX2ZCV7srnvKR54ugafrIRPdiVJNh54ugafrIRPdkVJNh54ukafrKRPNovuxQNP1/CTlfjJriyJAumLuoafrMRPNovuRdK3Wg0/WYmfbBbdi3xgQ/NTiZ9sxk/RHNjQ/FTyJ5tF96I9sKH5qeRPdoVJHPVOeKvxJyv5k11hEkd/YEPzU8mfrMl+erCKafzJSv5kzagM2mr8yUr+ZM1Agcdq+MlK/GTtSIHHavjJSvxk87ineLAga/jJSvxkc+NTPFhONf5kJX+yK02y8WA51QCUlQDK2kEXqdX4k5X8ydpRF6nV+JOV/MmuMMmmg1Vd409W8ie7wiSbDlZ1jT9ZyZ+sHQnrW40/WcmfbBbdS7oEmNX4k5X8yWbRvXSwM2j8yUr+ZHPnUzrYGTQAZSWAshlAHT0PDUBZCaDsSpNsOthdNABlJYCyK06y+pTscnVnQ/ppFt07+l00AmUlgbK580kfhFyu7mxIP80Eikkd6WM1AmUlgbKZQLE+kdBqBMpKAmVd9lO1T9BqBMpKAmV9dtODVUwjUFYSKJsJ1NHj0BCUlQjKZtW9o8ehISgrEZT1ZvA4NAJlJYGyIwJlNQJlJYGyPjvpwZquESgrCZRdeZI7GC5tNQRlJYKyK09yB8OlrYagrERQduVJbjkIkTUEZSWCsitPonBwdNEQlJUIyq48yR3MurUagrISQdmVJ7mDcaZWQ1BWIii78iR3MPLSagiq/uN//PGPy9vP8/1xfv0/b6/nf/7j3/793//xn5e3x/n+drr+44//fv6P9d+feYT17/3j3/77H2ui4N/++3/+54/6d57/6w/8gfXa8y/+5/X08Xi/fVwel9tba46JN3MhhvzfU5y0e3p5XH6eW4MmLJtBjib+hp2X29vb+UV+xeQ2g08V3dXCU9shfwg2f3hWueYPNpUPsXx4HqryB1/+K0dL+eCofEgmf/Cm/IsP5V8C1Q+ufojFTqxfI4ZiMC3ljybH5UP05ak+pzSXT87WT6l8bXpqYZdP1Rg91ZHKJxPrp1AM07NwvHyypn6K9b99JjzKp3qTZFO96jjVT/hrHn/Nm3rVx2o5MD7Vx0ixPhqK9XYp4n4T7jfhflN9dLzgJ1yqPab6uzBVe/zUUyu/ubH1UyhPjZ8FweWTr//tM8dbPtn6X9j6rdjh7+LO2VP9L3z9puxT+S/W+XBTXvz62jpubF4tyl41Y+J+/vjo3ijP7RuVf7d/behy/3F77V9NExtDIT+QGUPvn/fL18v53hoLzbJRX67ftff8P57eXru75fZ158CT68dm9ON8/3l5Ob+eHqferm/tZk/6PbuPr6e3j/fzufuRiZv1+Cnq+Ptm5e9EZmlN/vZj/XicHp+9CxG1N2+nXaiafJy+XLvv2HhSeZvyyvxbRj/vb7evX/tbp/bW/3cm33qL7VsYp93pvz5P18vj7/4pti9icJOLwvul+Pn9/F+f549HbzK0Jv3vm/x4v7199K85L53NSU9/v7yeny9Ob8p0piafXjWlOKLp7nf2dXm/nO/3272PgxoPnL7F1Yz60FzqFtnpH+Lt9jj9PF2uzxdk9yVd481x8qV7v6jfz3dhFU/e8efj1j/+1D3+yffr83G73l7+ej1fT90LYVtzqxrkrDm55Nl2yVsnacxY+nLqH9LzKNLExpPu+rTyee+D7DaIXUnanKHH43z/u991On83NWoJNSJjhJIcawzH0eNTSPVTqpFvQoyUEMmkGvNy8vhUYz2zLIhkmOsni0+uxsvPGbblU6qfaEF8zfg3Wy0/Jw6UTzWGW/W3y6cagBvEsatyYPlUo/JVrql8qlHfqpFRPtWIdm2BzZ/Mgk9cLT9bIsqnGqevRaTlU6zfHtHhmoD+jR/25XJ/+byeHrf711N/Qtl+43rimDR8PZ9en8e+y8d5vdC98dS98dMW9VOUa16NNHe4+3I9X7pYx7ZhxDqteNLMcJH0zSvynLw3afPj5fT21sekvolKnpPvfsPS7f35wETc3W0JZm6xfNrTI9DnGOfG3vb+hcnl5Xp5e31crp2XUBsqlvdkMryDvZfr7UMEoKaNmX7XnBLVm2Dbe3dz+z5M3t7PIqhrzFGa26xh7fD3aU8e0c96N6yqCRYybfoizTplNbqPoEJ7iIth9n357MOJ2J6GEmPPqCfiteh0yvLttQ+SuTtq+Lrjxbp7cGQkalxdsZ8Z37m/1nt/e1qoiZxJb7jpjhq7VXfyvPDltjvEGdtF4bMv0e3xLs//ZHzrQbM/y6Gbxy6dkOaOl097e1+M7YpWMl8zptSTX7sNpMklsZgSb1y7DaS5SPnL/fLt++NNpl5iG74lg8DL4VMNmTghZFoY4YzfwpTq9KYm1NYywt/7btfzz/O197LubZtdCT+vX3Tnb1fpRJM73uf1y6GvuW6Z+Q2De2dLnbNNRlgvp+vly/30EMda261RdfULk8szjL72K3MXLyBqXTziV5p7Q6p9sZU8NfHbDaoGvssWPi9zG+vL+XK9vH27Pv2qT2Y1b06JT9zkM2lMqr6VOt9ykz9fY/X9futf8za7Wr7r3OLYWj3y3C4NmSaPkp1hxYO7TXdyS3j5/oxzr/y013nxs3ejPVvW/HZEzjtuu2/CSdFgwQqIQJcAV8Jpb8EpzuLcFzwcDZ8Y5zScuhhnLUOIJyq/WNtI5m78cn195h36Ba/LwU3uhi/X8+nt871zn9CunPVdYoNHZutDYYvDta1rPDtTj+gOKMJX4MIeR2pr5pbk5zfszjKxc+/527yf317uf7/vjn+NucktcbX2fvr4+HW7dwsdU+N4iWatyUNGapZLV+FdSABKADsRSYZlkqKsf+z19qtHncvS/kG8Lm5uV1pt9j7EC7UWAyxOrhbX2+drWX/Ob8+zsThtt9msJUw+Z5lZazP15Z6rF4O2UU0LEYMZWvwO9eEjwTP5I9yu/UH/2R/Rvrv1DUpui6GQmllmb/d6uz8Dhs612tNhuQ83F2ut9naxfIxdGFhZYQpbdmly432af5x/vJ/vp8fnXZwYuqgk1SUpme1BbX8ZV9P2HTwe3uy3WffpHkh0m8rksawY+nq6XM+vuwRPG7bQZGZ94xuffcLDdBnVlCY30Wzu8fd7/8ipy4dPHvlLgq1bXpufLs0+/Jqme1x+nG+fj/1za8ki/7ZVca+hPV/VEwoHuFSMeAsJnxxcLyHaXBDYIvW6+C1xXN9grCnrTNnyCechQnKaGZ8QfPCWhsBfe0o7lU8OKV/EwBYBiTXYeyfRV//MPvo12HRr8PSP8PG4f748BLJqfoFY9rv6GLDt1cQ2EZbkulozqj1Q4lH/K1svofojbqUSNSipvzRWLYR9iNIIz7Mu9hVP2PrXn6VkeUWtX9XV+MjVH9/XhJKvMWaotwOHC3W5itVyrN6R6laDnSHV50UL1Qe0uO2Z1c2KDKppqjEqXGqtoam7G9djO5ka55KpGVkylbqQrWECWYeHXqkGoZKEHP6ax1/z+Gs+VssBP2bw+Mnq60YRdToR95twv3gZKdU6LV7w6y6+foILMWFjJQSujN0EfsAGwZBxCHWX+l9YcClbvxU7/F3cOXssGx7Lhp9fDB+nl8fH+e2jf2eozZ666m+/Z1M94NmlYxnTO2a2uTvb2aVbKHh23/zsoU+bgCEzGbLcz6fH+bmJdF+oPW8bO3uK/7zfz/1Xsi15XvW+fsPQ++1Xj2iemtsNMp5MMr983h+nS5/la4OKuiJN/ojZmumPg4254ttuLjVazCkUpd2/Z1+EYkzJoNil/UWX2YNlNlgKMi4iKcNdsdVkmVsxef7n4/z2en69vH299d/Tdd9z8jCUje5IT5tGp8lkdbH1fvoUv0ibLaU0ee7Lxg6XkdjerJ1+zbJNHRm1OQ5Kv/X8tJWpfeOWybPpPh/W3ecyd5+v5y+f37pba25s0oKoOXmqfLRnMZyDUHXAcTsRzf3Er+fr+XH+df7y/Xb7q/8l2izM5Fnj9fzxuN+6L92SZJqsJnk9P7bjVP+LtqmrtUd7zt7Tf1++i3XULr57W1ELYucWrGz2Ig6R3UEf0UAALAkJmcmIMy1qcFEtzKn+/8wCgLJ45C1x9l0SQlnAF3JbRQriW0AaRjULW3gO6l/Mgk+8VZUA4XgQTITQ1s4tnuV5yTWz5fhm8bOe9rR1vfQ1hZa6V7UG8GsjW/k0mSff7GslabbdM80y/a49bf44vZ2+9ZFBC15pssg5G1v/q25X60p9J8tUiq3b4+vt822fxGjpE9nfMXn7eb7fL69rNeT59fN+eft20OjQpa1+5/XreXHXgYECKPtbTqXsI9y56CRqzNZkLqIFIVTdklGFsBWQ1UN9PXyZel629ehl6/nDoQCgnjBdPRb6mrHzNW0W6kE31KUm1FNdrF8j1tUABXc4geEARgsOdIvDEbU2DhDhCEg4cDIOnIwmCxzFCGdyMsjAonSNbM2Jk0W7BZgEOeQFHP6ax1/ztWiPfM0NUGB8wgE2EjK/OHBG3G/C/Sbcb6qPjhf8hAuOhYRjIWEjIOR+GSWRHHAIrUdeNh6H0AWH0Lpcs8UxGM0sjDtnTziE1m/KHkWUAYff0LR54NNk0PV6ue9fYxO7Ul1EI4uf3PgvH1qGsQmqJ8PgzdDp2lUNuOb1m4yCV1s/+xWbQsvi/OSCVQz9vVthibsz2ORqVc0pBXyWuyP+7FO73e7yFMKpyxMbkB74YvTgSbVIlRN8O22eBYqyWJTOIndJKAqkgOJYhBhYINepj+VTRC6UELLYrYhr0o9vt/uOLz8nYLc8Yvsak7vfp1bC0JVXTSYTXj8/Hl8ub1+eG3PPttoIxE4evoq18moI5taSnlWRYcbi+evX88uj34RT827YmptzdR/zdamOAG4eDX4BNC4gqYc2RzaTZTnn6/nlcb+8KCkdY7sAKYHMozLaTOY+6h+5PP6+fX0VJzXb1b43tds4n02i1wxH++xWm2Owk3Av25GmQtc0QHPLWDa1VoRfHl/u59NfIs/VFvuakkaetdpw4T6u7R7oJBAuNhFxPpuKr9fLt/Pbi3gOXcJw1stW619P1+uXU1+pYUP3E9HcSpTt3c+Pvo/CtgxxldCaM1ZLIS4/+5NLl0kLs7darf117r8cdQmvyZLczdyuGYa6I/nkTrjbT9vNGbvP5IL2z/PL5+P88XJ+Ewm0FlEvc0eAr6fv9/Pb9/OlP6W2hzRD2yY3mdfUejHN0tXc1gWVEeRznP3O58fL99P7pf/GXT3GZDbo27lP8Lc8Y7IJ9dv5MeqPp/aut7ZpswW4iCTKB0QP9YBk6wHJ1rDY1ZOGq8U3rm4Tvlaa+VD+JdT/c6gpF1QvxPo1Yj3UpYpxUsXCqJwlJHkITUlElQATCtEILUbE4KVoIiIOOEMBrQFokgFas9hnrQPmQzu+q6lFQoUXefw1j9OZj9u+jU84z0Xgu1hvlyLuN+F+E+4XBR284CdccFqh+vQYVJ0JpxqcKBlNU2zA+g1iVFujUAbWZIs2e9w5O5zJPKqxPNrsw2QW+Om/75eX60WEIdQ1xPi5LfLb+fHl9HF5kRk0annedtI025tf34IaJiOdV39yW5+3rcGWq7+eqw/b1TAGdNfX9yvU/3OovyWynLF+jVgfaKqpjVRfGdQ+0QLQj9JhogW+D0yNckzirZALfskBHo9SAkhjEIqFyELWAe0YZJHBcADq8AXy+Gve4s0AFA8QlggBmQQIQcR6uxRxvwn3m3C/qDfhBT/hghiYAKyR5GVCiSvX8w+jEJXRJsgGMbUFKIdABlu8fbhzdnU9YY/MhEdmIkzuqavj7htEu34TAyEMiyZPZHrY4pk4FPu6gPeyPmP2SJDbyXrJ53dTO+qo69vyc4HS09rfP04v3b7XZvzMXIy92pGpw/bIVxRTZgz1kbrY2antGyYEC3CAuEGDunbUE3t9UWz1Uls3C1d/D1dd1C84/dV/qatSqP/nUN8ApKVi/RqxumGqgBqbRtrKh3CeRE0W0YIVA3sk8gvE2CMBQggxAxkIvCAHSwbZQIv8ocV7betuRPBSwhtEKBIhj5olD1GagAxmwJ6LxjGK2CMj7jfhfhPuF9CIF/yEC6q0CXW6hGIXQs6Ga4zBDDCF3h02yGpaZDUt9hrEDuyQIXJo4PZogPNo7w6THUA7BxZnWGqrT8htX7c6MLqq69EbJXn117L1Udm6zrv6hV19Tr5uQpAH8vXVQGFTqD8DEkaxfo1Y16pUgwms91juCapABM5HhJqqrSyZsL3xVikHl8J2TyhpI4PqKhS1kUUAZuFctm4khJ+RsMwSlILIWzg1Arpg8AnbZUSYGbG9Rdwvevgp4X5Tffd5wU+I5DQTQjFCKMYLPtXwgMHBGaWTbKB4ZEFbLRY8bPvscHZyCCR9vQ/2aJcIk2XaTwe+vX299MUAXYIR9WaTvTbZZDkP7QqpXLNNTCbzO4OP++lFpHSorb+B8AFvyWC0v9TjFQB09Shbf05bF0RXH6qrv6WvqzWADcoHkRgM1VWQu4v1a0AxAoWDWBixLhI4DS0erxbEvwj7AGEfYOwDDLfHvkjQXiMDLgX1NULpKFm8ALauuARXI6yVBHZDHuc2j3gxGHzCvhIRxUbsAxH3iwZnSrjfhFPTgp9wQaRHiPQIkd7mojhrMvLvjEIBNmBQFgzKYlHG/sgOpzWHONXjtObRiRQmixOfDpyTvc9iwGf52ON0f+wKA12b4jaTrUXfzo+9PFALmokQpv+mxT5v3qWm57fHYmofL1KXhZ5frnRwTUtXj4pffNNwqWtAPVyiE6w6vK3eZuue4upv7qqroYjY13AEMnxQ4QvVk5FZj/VroPcUAnzYW7C10IJYa/F480GLt4ryraScsZUy3kqEFgRYT5BfIeB6sltjEd5Ph8wO3gTCdkMef83j1OoR9wWDT9iaI6LRiK004n7RvU0J95twZlzwEy44URFOVITaeYa0IE7azCiLNhDkMQHbK14MZJkYIQY7nFUd4k2Ps6pHxiYs00edikTPr8r7FTrFhOl1pSVw+9IQ7iQFDJJVFskqpBYYCz87hNoOkYpHqO3rMd3Y31iiBNrTvqrpvip+G2QUcJJh+Cc7BFUO671HUOUhVWQnS7a/nR9H1bPc1s5FvCGbaMYy/zgqlvl+enu9nu9K0RW11X9bLgUbU/Xsrfmm7uC2fjVb3xxbt29X/dfV1wbCor4+SNSgoAQl1Lcy1m021q+B1iRUn2Abxy5OC0LvxWMVg0AqhGMJDY3EiFoYKwyiODKQT0W+nAwCfdQfkcVa45Cjw1tN2NnJ4695nKQ9jgEB2eaAKAiNMQRBMIIMGKGRmxLuN+HlQiEnLziBopOICSdQNMcwTv/MkEo1qKsxOD9DVpZxZGLcOTtERg6rot9akDaphWU6l9TXltLSJoCadpXqsWhMr+tH3W/Q0YIOMVs3G1ffLlcfDOqmfL0hX+8n1P8zxG1i3RRi/Rqoak01ZMemgz2HFsSxC5qBAMIIdXFE2GMZeyzDhxBzEKRwCbltMoiaLWJgC29yyAxhMSbsQ+Tx1zyOzh4xNcTsKGxNZ9jloU5BkB4gNM5Swr6GbkJe8BMuOHKih5AJR05IyTGO+8yoBDPQaDE4MKNqjnH+YNw5O+zjDn7vsY97HJjDpDTZ6rHdntPWlNCkjNjTyo5wtHY2sWPoKgGh1u2orkxQvLP1Gdu6LLm6xrj6gH1dM4G4fH0uof6f0bwW6/IR69dAvVuqgSqWJ6xOBLJFaFsjWuDvWI0JqzFjNWb4InYnQsUgITNLBrGi3fol4ZUOKSXs7YQwhKDkQB7nWchBE6Q2KGB1hxA4QXSDUAlGaOGmBPqwYM1c8BMuOAduHbqEcyAqR5kbGXTs2RD2MDjFWpxiEXUz7pwdVnyH9wedm+y3Yv1JYadv58dTrmMX0fjuSIcXDwqUvCD0JYS+hCVi0xqZ7f/5dn4I/EBtE8x2osc3QJE8SuzqGonCU1t/JVu/LZogXf2JfF29AcZ8fbKh/p9R0xXrQgYpwFiX8lQfAxZKwkJJAGIE3XRq2oaxMaAFmKC5SdDXJGyUhLoAQlaYUBlAFmGGhWM7pIqw3RMCYwIqJvSBEgpvCcWTFLDRoOSaUEZJCfeLHh9KwGMLnBjiR7zgFEE4RdBWQAc5F94KzlG4bKDpYHD8szj+IcRj3Dk7bD4OryCq+hh9zxxoruLk2/kh+xioE3fEd9hkYreKuuq0FULVr2mra9n6cNCz7Oqj9nXhBZFBSQMqGqD4H+saBLVatCqjmAFrHGGNI5AYQmU4bfIjaFQmwprOWNMhLETY4wgYn5BlJYB8Qj0LoVudHHIb2PEJMSqB7BIGAJBH5BK22kzsERG7SsT9Jtwvan9pE+Rd4DyQWeIF50m09zOkdJlRp4ETCnNChIP6EDSss0WMjyiPcefssG84uD7mXbDfauInJV6eTnt+/Lrd/xoeuVuGjPkUjPIbxrbMbsFbhbfU4YbRx8Fo5DB2vohqLWcT2cZW7WQ+zbq/SeqkKPHocTv4waF7UR87msls/ZnQcG+rc6C/wVVXQyUSKBQqMFCAgZ6OWL8GpMEwowO1F1hbCTs0gT7RghkhaOcglJoRYS+BmAehRJ2wuRL4OSEtSiDohPIbQr00wR8IwQohTCeUPBBaPMgj6ApIKgbsTRG7WcT9Jtxvwv1CB5UXvDwLwqUFR1voJTH0JhglaYxDGjP0FwzKWdDWwyjBYeyx7LBfQV6DHax4vPoeB/MwObPn2/nxON2fwZpUk+RulgXUwAlaJIYmqzO/5VVBWwxctxhgCUDghxWbHVY/1M0zJEbY40F6dFfY2cqS+7lv8DCprRyFH3BCG4aZlOv7dr/1ImGGO0Ul/FxxtnruaXDf4tg1pITJuPhpSusQ7xo5JxtZn0nFncRaq6eE0gyOk8/uaVIorLVNh5vcfZzsPvx+6g/irXtP6hJ8P33IaqFOJRNbF1YHtBjX3Qp1lxApwlgiKKqgd8/VdQlVdkCgqJNBmUyoy1SsqwU6ktCyB/aJQIQQPRPQJy2YKkWAryijJELgxZscEdZcRKKEAhNCophQYkIokiIM4iKsc4SImnAcJRTNkMfBPuBkEJBmDQjkIkI/yAlRwv0m3O8m3IvpCIyWLF6QCiI4HbrIGeWWjGQEMxYmg6IjSP0y6kwYextDP4kxhIwxhYw9rHgc58OkdMD304csEOrUUjeNS6xzaPypRQz1a6LDHX2XmKTl6mYKDSBUdwHZoTQGlTEQAYh1eY/1a8QaKYDVYR8mBM8EVEcoiybQZ0L5HhHiDt7kDeFFCMQI9RqEVDGhYoNQF0XoNCZsTISAmnAKJNTJkMd5OuBgEJBohQAWoUieMEaOEu434X6h2MpQbOUFIf2CJA4hiYO2Y0aZHyMHwAxvM9jxDA4kKNtgvK2MuXmMLmtGmzWjM4DRGsBhUp7i++lD1RptezjTZDnr988v3Hl/mzitx9+5POz3zy+9TlCn6VNMTe4kn19UsQzTNa3gZQdUMCUfPvMHjlRqWp0fQ5NlFU97igxAGyzMyjl+//xxed3NkOsGVdX9bzJUgEHuA5DGIoopftOiKr7URnFmVp9is3n4w7TiPNMxSWN2Pz2uVdjiSczWWNz/4u00EEOTIlubRU3s33W//O/etaL5307a4sl8dTYoZrx1GQHgDUOb+i3K+0AfDeMwz5NTEPs1oNU0Bf1gZBNxvqlYAqWsANKge7buIA4C7jWKczU/htMjDo8B+ss1qAt1f0SeK9bdB/qg0OnBUE/CgClasNVCnIcIWxkh3ESOhABxCd3OBNVhMkgA4NRI4BuEKmxCHxMhPiGHvwa6RSitIpBdAtolRNYUwe0jQgsEKgS+Swn3i8FbjBorRgKFcZjmrdOAsIVuNdvoYmMk6NlsSWDkEi2COItENE4TjDtn1FMxQmlGhpPxK5vCoP61BwvM0y4Sswbup/v59X7+cXsoKkadbNnkCfLy9uO20xxYuhkZW20LHhwSuAzqwDgpcKqxjFkwdQxRlwF5MWiuMKhNN0jgGsZpEOcms5XXoEXLGKjtm8lD7uX2+PL5ePQ3bdvaasOT7fyXjzJ/VvbbG9/NrpqMwy7PozMGf/V9RW0aaFKZ6PI81RyY6wQNJp/bx78QYKd2ZhpPchxorvS22qLbyc7hy0dpERdNzr4bpTVZDXb5WLu7Lm9dBX4rfUCTGgV/0fJ+v73cfny55Y99uN58t1rqNecsf53/lmuAMd2bO9lY/9f57/dTf4joav7Kt5p7btmYFhS1EgI02RmXrT1uny/fu+/X/qLQrJqyeD29/PXr9DgLof1uEs02wXGb7jEZFD/Hxn++v6r6sp0iw6Qm7/V8+usoFDbdGWVS3WI1qPw6nbjApArOOrZlP2Kpi1XBPxkAwSyQz14gsUebpDYqNxlNV2YykVMm1Dz06VTUDvXgSWRXTe6mM1CrYc+TLKGzdjDXgFrpKv6dO1dPDu1KP5lb2IyJQ0PbGjBZDC3XqBYczM6tlUNtOhVe1B0WP4NiFMO7GKKODC14RkTNvOGaSXWv5xdST72mO+xPahg/rclbpHYD5Mmt5mlEbjDtz1/LFea/1uHa057uZztYVoM71aylG1C01aUiyxyRsYvbrF4UgyHbxwnCHQukvRaLaBP/hnYtg2yfoUb0A5+2sXTI8jJa1LbC2W0IABTxjZmcjFYfiViOWxFnw5PSQk9bu4Edpnu6k9I4T0ufb3uXbHfJ6S/17ZtUeupEyCYTYtfbt91O0zykunnYSSF5Ue7WijWjIAxJCpwsUTCMrj2UC6Nm0lafchiyVo+trqJ7oFiQ2FBLh0M9a4aaqQCCjzV7D+FfSEpCUZIwS5EWJNMXJOcJiJ+AAlDoRSiNJSiKEgZHkwFuAqYhlHwRmmIJihDkgJYc/hoq/gitDYR6WULBLIF6UERVdQRAi7hfVM0S5HEI+jiMHgcGnGfgOt4avwmd6Ft7KvRAGLVTjCpHRvEJWyxPGHTByKQw7pzRz8DAHIziC4OSTkOTkks/Ti9i0G03p3SSSv843f86//N9PX8dCGl2NQ6zVj9kiG06ievJDP2P0z9XabOnDsiP94dQ9e6kBydFFn88D+vfRG1At0ZuwpSot0JjiUGzk7GTB6IfZ/EkelG6sg7M7e+rrferrBBpf/a6rvyGPREwdHLxxdzceaCae7lxv8O3ialicW4jWi0exSDtcALD/BuPUNtxW60yntSx3M09WzonR5k6ksQcEZKCXDLqqThhaUrIuqVtLirC1AXyzk2l0SaPiuFS1Ig44VPdewxv6fi4HbSQYUN2zkwOjXw+jf4kuHQD2rbi8a0FA7n7uM0FRqlyQjCYtqF69RGZBTl9FDIbrO2GtoTjpkaDEBBSNYa3YbOoad9ktKEpbczkhOX1IXy9X85vr9e/d1VIvpuYPtn8uJrcmVo6sdmtxhnRC/ADA41zwpNP2G8WhK8LohqUBxjaTuibKAqcDtl3w3C6pswa+AUswpjJYZo5Lb2fb9RmuFAhMbmZFJMHq0mbn+LJ8T/FpLKctPmUWR2oH7ef59fzY5cLNR2si9vwWWxLjNG0pZlp6m+t/9DVtXWCjbS9I7A+qUr64/ZTZE6N6dYClHKiqIXRzGGWyTl08p1oRae3UV6ogQZkqBAMffdofULzhq0P1GEeZl3DXaVzqDhCwVGoDh9qhBfq+QBlVrGiOiz2AGHgYIRJgbSgWn9BoS6B+xG4H8AJoUmHwEEJA+vIoAAHhSuEGniC6gZBO40wuZcc/hpaIAjtnoTOHULrDgVwxIgOMUynpYj7Rf8OQd6PoO/H6PtkFN3xJp+xKcsQ5Hg2gQkoczGKqdlsNYhNvTnaWEAjcX5h3Dmjx5M9ur/DNuFxclTz2/nL5/Xy/1a57/PXr5eXy/ntpefqHUuJGzSbDDtlm0H3nrd1naZUz/9ri7edEHRnhmfN9BK5zbIw9+xuX78+MxNvt8fl6+Vlp5jOvtMvQc0gMkG84JhGOKbhOMy8hRCTOki3t/H36VomUA+GGI4XOBzB4fBiM29b8SQHyxtS/5D7bdNOGpKq/u3+gJcDvklxEw9FaLlMBjnPv6WLnnJXjDZvTZ81YbqwaXKc3tPcPnHZ0YS4MQ2e2+1v98u3y9vpuh9j297wJtEy+VU/H8/hBLtTp+nON3W7mjP583y/3npCaF2XoZwk7++n3p+68XJmcmLv++l+2t0exc7BseVPUsHd5DtuT3LYAfEjU9y0LnGAWCY7q97P95fz20NkIWz3C5Uk5L+29f3vj8vL6aqrL9nUrdCTef/366cI3Vr9q+I6c974NKVyklZkyvDkmOCntR+Xt8v/7ftFOhn+8vUmf/ZisA/eO65aq7smf9rr57fDA0aHTCYz8avB/fHCdYeVyX3qaetx+/ZNlIK040p5Mr5fTSmw0XflpPO3qLBG31VGTL4NP9j1h+SuzAU9hUiyc5ykwO+36/Xy9e18fhUlL+1khK0FHynhbdh83cUrBYekOOrRMJ4JeuKu5oggogkpHKj7QdwPsTbmIwOcIV0ORRF0cxD69QgSOAThaIJ8OiFZToTkOwgZAdUT2nnIbPO3IfkDVTeCtCOhApPQ4UHoZiU03hKk/gihNwX0IiK9RAEHESipEtJLlHC/yLFRQvQHcshIL/ECnEDoIoSgPkMUidF2zYzyRAOcABl9hrQbo0OCMYyNUX3KKD9laKczxNM5TPL3p+dqftvq8m0K32CpyHvVJED9qhABB/dAGSUUwDFUDLqUEMSBIh0E6aD9H6uTI0kat2nv9ayMAyW6kAhCOATRYoLgOeF4SITjJiOqAs8ltPQQlJAIuIeg3kWQIySQPkKXB6H3lNCFTZCnI48u3oAOK6TuKKBIFuKkhCQeJdwv0qKUcEpAbpiRxOMFB2hCYA4JfIY0EqPzmBkeZ3CAhvA9Q8KL8cYyiqYZlJOBORm63Qzhbg6TtQzaoF/TomMGD2VIKpgFqVtMuzfLbNwjZ28b6nJWoHZxG7yKLARQLEMx0qCt3RiUlIGimk3t1k4W9L/fz88Sx7OSFW3TjSDJv2lUD1vaYiRjfvebKqFL+1XNZNJgtdeXOqY21EhgC2kbZjxZffO03QO1lgduA5PjZEnHf32e739rs5G7kuDJOoX76dfp9eduuHSnEBQnzx3306+doaWDkdt0Pmx+SFcyNk5OoA1py9ki179gWg6CB4NsrKFN9RmJFjB3s01fbbqCka5F7tKYSWGj+7k/traxLk32k99FMr4dVMdp06nYatMni8ju52+XJyYXqpP9Nt3KTW7DLgAH8TfrqlJXZszDQGIT1QkYM4BeB7Q6QL0LQovQWcRwklh/N8A7zOeBiAsCKkLjJUG1iyDNTpgtQNAGJoycJkZ3CVAlIaImyLYR8rkEyUKCyiYhlU8Isgj6CASJCIKUKmFiDwU0leLwQBh8S9APJmxFlHC/YG2EUesMesnYnhhDuZmQVMC0CYaOG6MNghkbrAEmxowJRmcTI0Bh1CIxMAaDYzCmEzDGE3CYrO+6P+fNf/y6PF6+U79VN8s8lLx+2+T7j85oe4SuSku//T3VhERb2mrMZL9GY/Rw+0yd3d9+AsoO2h6yjZkcTZ6bhvqFrDFTFXDmtvdsTPtqbQ7LTKKKp7WfPchr84KThUy7CIHbkg4ykx2oa7nR5e3yuDyTatfT3z/6O2xnFZsiwjJn9Mfpn6pB6gzOxSz38zNj8ri9ysLodmwQY2wHozqRsRoyyCZjZB1jZh1jmAJjmoKxs+57+3J7/Dy9fH7+eLmeT2/n+7Px5SpFVBrwU+U5Jn+jnf2Pbu1p08qQ2Zz0IsX07pu3k2qRc5kz//Fx6QO57kCDw3YRTPqX9p49SpLKcdd9PBnkPA09O1Zun31FQOxmvU7WWK26Ybv+xLYNy5jJAjCYup8/3p/FG73JLjM9WaW2VzVzSzd7drKc5OP8cj+Lp9XZmeRAH+e317IldaFquwZuIvpzS2pj8+P8X59ydC1R2z+9JaFQboUzag24aySBMU62Bn/A5Rj+g5JXVLxC1xJqyBBDhr5TrMsRKpgw8A7yUsh3EJo8CKqohGEkhIk/BIl2IuR3GHlJFH8REl4EcUiC0BxBD5gghU2Y/EnIgRB0aQiyWwTZe8IIPArIQeLIRegfJ8i4Ew5flHC/OOoShqTzss0SQRZmQQ6S0CKNPluGwilD4YUZASEGojOG0jBKYxh3zg65T8x7ZAx8ZDSMM4ZxMCafcto+NbAY55lJNvl09B+f18fl/TmyeR/XUSdl0qSt6t/e5Mqqp9eC/vqrYuKnrUcFTOBBWQiqQiCGCfVjiB9jwBUa5HHKxng2NFHjyECoYCAotxJGbhDG7hBtA2BxRGJkMlGeRzgzEhQVCYJbBPVegvQ1Ybon4RhBULMhKDCR30azI98fkLUMaB9AZwNB/p0w7ZYS7hdpBoKqHKMojRccZBZkLQl5cvTzMGRRGYyCGWEOuscZo1cYYqiMO2eHbCmmEzLGEzJaGRhjGhjTTTltnxpWvC2xs0t6Xsf3U4WoCyJm9+hi7u3zxxeR9Vw6/b2t6R+JZfxYjKQ0p03ODY1RC9pl8GMZJOYNbdWm2xQgFLuggsuwx79tqlsYzYw5xcZMYtCDk5rp6nTiZKj7cX6cPh99Ab3pkkyYToHpOIYmj5cf6+je8+f92v/cbVZ6MoF63BObmpgFUiCY4AxhdwiGxk3gHXQkIOkRUF6Iykdm7AhmS9PyFmsg0TdJ7T/WWeNvb+drF/Wz68Z6u9811usiuW468mS39occO6mJJHSKWFuGZktgw5/rjlSLU+vqi+m7aLXCPCgMHYaoOMRLICkORXFoZ6HFKtZADfMW0V6JaINQw0aQZSaMoCAMTSHahjEjumIk7VBUTAg3CQqQBDk9gnALQVCeMDOWcIglJLYI+mqEsRSECYwUEEkFMOaAPQytCYTJ05Rwv8j2EjROGMSJIeDDCxJ0EPBh9GIwNH+ZtwFC2EvQd8HQKmIo/TLunB0Sgxg3yn6bCQkrEOvhMFlFoTa7p7ZOsz5gjKlFR9sm+YNxfBSwowfQ0bARcnxns+XS0XCXttLzyRKctrm+vwPX3gFINV6Typw3ZWRERQHp4rARUpzJzLb1ocQ4behvksP9K1GAVj4Cc0cxARJkeauuxkAwCnDggANK2HLI6LcxjbwlCA92XzOZvv1ox4Je3h7n6/Xy7RlqaIthq2i3NeQjN472yBooYgAZpsRh3DfmRGKYFGbjQawemX0IOYUtj1wdgODL9UP90VExgoCUUDBCkLsmTCUhzOMh2qZLIwBnjHEA9yKcSAjSooSaIULXKWFQAWH+MOE4RsjoEYpICJNKCPPXKODbB2zrmENMmLNBGKVN0DIjRHyExnsGBWR0HzPUzBjdx4yeLIY8LoPxMGg5g/gxGq0ZoriMO2eHwyTGwjLmwjIG8zA6jTlMAtiP8+P89atoiaVWfw6zCTG6DAf96Lb9BysfhNfCdgoBWjVbBQ4EvjEPyJhJ2JG/tNJVwKbLKkEXDtNzDE3qIz3/RFZbEjUaLQKYFc782EbvqYtE+6W35APQM5r/ayRZN0nMU4TaHaYpYn4XxndBHB+nV3RnQwMNs+YiYbsABK1Jqrr8IEYgVOcQFJMJTYu01XjTNsEbMRFUDQkHIUKQSKgrJBRoEZpaCIMRCPOTCSdZQs6GULFDmMhCGORFAd8+YHfHDFXCXBPCuHKCQAEl3C/6WBnHQkZzE0OigNHcxGg4ZOgRMzJ2bHD0NJsAJFAqVIgZd84O53DMjWUMjmVMIGI0MnGYTrc+vp7ePt7PwnHbQR4Yr4bJmZBMQP/Qpn6CfA2HSXD1oc0nMN3LiIavTWKJJtszntYVBQ7qCrKmc3aP6+3tm1J30xxFt07VONl+/JR2Pb19nsQTMN0TQH0gWidpsnpGU45tC4W2jh3kOmpku8nCVF/ETEg03GF2KsarYboaNN1x4IY6NlrMMVIwVidHXwImYCJzjP2aUI9AEGgkSLkThnUQbVPPER1AHoUYoT4CNkLhKKEkhSCNTtDzJwx1JhxoCCk2Qo0CYeoOYc4aBXz7sCmDbBNg8Tcw4p3Qc0kJ94vecl6wQCyIRdB1yQSPRA0TowCacZxlA6lxsynJ4LiDsmfGnbPDgRADYBkTYBlTphhjphhDrRmjDRhJZEOTUz0+zg9dQty27+H0AvF+vn88C5remvhfYYq+eyOnXz6tHpRbgQGMVou8ucDWpQOxgMmBks8/eT9/Pd/v59ftfvrXv72T7WCO9OfGzevrX0ux6g6ICdcYCItZW5gPB3l85DBQ9I6ad/RTx7pW4IYxThTJC+zEBG5EkEojqOITJjkQbQPPEXmgr5oY52SEYoSCNAI6JHQ8EEYjEGYgE0J4Qj6DUI5AmGRFmBRHAd8+bC3FKACDWi1hujuhXJcS7hdCCLzgNVwQZRDyMoTcJdLVjDpyxgGOIcDMZmtBR9YA1eOMO2eHIxCm6TLG6TLmVTEGVnGYrDvJPqztXO1UIQxDgzo0po+jTH0TmEAUymE+jb0WwKihfds+sx3nUEta3xzocNTfEspTUOTBhFpMvsK0OnSOICmFwj7U9WG6ImR/Yl2MMZcUR17sGQQgRWgwJqgNEgZLEG0ztrFHQlaOGLkaBA0E+E5gkoTmC0LXEGEoMyHAJZyCCTiWIGJOmFtHkDEnVLcT5igQ+ocIA8Up4b9IuF/UXPMCV14QwBISfBB8ZkwtZNR4MqIIhuYYQ2eNMfaMUdnJuHN2OCBgLC9DuZwxEIgxEYjDZKXVx/nxcf72Y93URE6UXd9Ds61GKAudP/+WP7LPNbDrSoDD9oPhBDa/iX6+q4XpbU/07NJyvbye1R4N0/XcwTXiJtwzqXb1cft8EzoonZLzpJjpx+N0fzzrm7oe63brnix1VaQru6Fim0wl8peACIy6YE5blhWyS4g8DSCCQW20wVgpg/fG8KbOAlCEN8g0fYf1jTQ4JhszKSSwL/A01M1e2cSsUHaCTCGjZIXT1g4JjSVstgaZQoOyHUNbD8E2nx7kGHMPDEIP03Ss1bXAIP42dlK3Lt/xi9gtW3XoLTeAprmIYBzj3I1FTYudbEHPf1qRp2ux5qQw88fj9r7z+HannWzz/XjcL+9qubTvuoJmK+ae5lZt4b7xvcmlIoSfN3hUee27RqPJ+s9sUSls7jRLZ4sqP798vNwvX86tNkhnt0X5NDlO9ePz5UVkTkzX57/M7jprgfmXW5/a9u2aNilFD0tfruedClzzM0yu+9Ka1HlqRzXYyYdWbb7c3r5evvW/bacjOdkQDoNKPU7oCmgmXbna28mBUCezs0w+w7/fXj4fLzsRetdpJk52yB0gSdPplMet2QubWZNl24p4kKUvXfK/8+c/Xk6i2rldPUzpX/7XFi9X0SrQhgNmcqqUVi/N3ZSDSV3sYqhvDGgbDWhS1O1pqNdadp3sy2TX3F4kgts+tG3SPEpTCO1mZHFUQFqL3CYOiNFMZjLz/Lj91asQ2S6rbmcfze325f+K0Lrt5CvZvX9tR1G9aJsuMKQYomoIBVw9zWIgMzrDUWqAymAUBseaE4DkeWoYEo6XW9UyziGo1SYL0IdcAyHVSBChJqhQU8ABchvggGCLISfHkNBj6FAwaocYE+45+S3fvokWovgW6hhmsgNJEQyJ7RZdbxgz0229IbcgwVaLVzBCwCPtUX8OTNqs6xfEWrcEMvS7iLaKWpzTUEdMFsQPx1VCxocgIkhQEaSAooFNDR+pAjbQjDBuy8kgFkXOCSPLOXmE2lvLLWQRTVN9PXdA+Hy7nh5iNEvoZwAhaWa3pNncKrQXoOcuNsHkNF6QNSfgPIj8M04QjHJow5Pngfwdfl0e32+fD/Vuu4kiyNlDjJdR8GZ4Mmr8fJtpDG5HYGzdopAUgN4AhFer82F2uq3O5eobjoHCmM2K5gWUjKDUE8ddHPFxDor1HAopX6RbkW0l1M0RlPAISisEJTyCqA4x9h1oGBOjlAXpdkLlJIG5EmonCbIlZMFDHZRlkD4iVHcT1PoJU1oJfQwUsI5CmJUgYEIR95twvwn3i/Z5hmw/L8gBE1ZeiBkz5koziocYz4A34TOD6nhMk2b0rjD2aMads0P6DRL9jKnEjLHEHKZf34njT+vEk5Ftnq7UH1naeBsH7/psbf2BUPmJvMU2MxhzxcmhGmN7IpBj5QXpRcKKDIlkxgRl3mZRMtqrMCOZ0VvB2JkZf5cd9lnIrDJ0n9hP4vD8nJT6cdcqRxs7eT7J5l5PvQgHdWqKqOaIWHKRLmao3HJC082CxXHBzoS+JQP8bJA8N6gRNOjnMqAwBsIIhgMSYAt2NUYCDE6CzheD1LopcHrykcixjtRO3NkarrbOj/p1IARTXc8yPLYGitXHMDYbalh+Gx1Qa5PqDaDKNtRXIFbLsd4uxDyQxUcSn1DER9DAImgJETSwCLJRxIAWEFYn+D2B4hDKOAmVEIRCToJSBWFiOjmIMuCtIFQ5ExSYCbpYhL4bCoitIDJN0KygiPtNuN+E+4WaBy+IYResB4QVchs+C1U03ubGMBrODAQYDN4DaKExKtsZMSLjztkh4vMAI9DTYghqcZhsOM1+q4KANnU/CUjE6mJT1zGMF9JOjkH+vF9Fb27XHz+ppP75cX6t0VPfdN7NopgEJ6UfXMuDdhzVTpZqZXtKlrE7SNrJQoWfp+vlNStJ71JHnVrB5JTnn+f75evfW3HnX+e/e5udCEetZav7oquvBvTPUEiIMnSU02OO7CZuBhFEcmicxQtAkBGjgEAN+sPM6KbBSC42k3Prfz6LVwTJoo5koSQIyyqjb4Yj4jLEeYyBRJzShj0AerZxiFvDHPR8UHthaDs5Y09Dh6fhZlgioEjAabo+VoOuZmP89gm0AuLFdjKf+vNyf3weyc667i2zk7jv5+0qNXFNN7wwbuMkMAJhG+xtJnPVv06Xx9fbfZ+2bSfs0qR26a/TvXOZxsTcc1xHkT5ncupzHzp1iI2OgRvS5DQN8Wf6VaKdfFFP6ZM628om4pYuPTdZE1oMKdn51K3/kynjYu71/Dhd+v3Epk6jYVJmudhbpd1UJYrU8aHJ6dHF6srldasdmZgcQfvrLAmb6WZJxlnfvny9SL0S67p0+6TQ2a/b6fL980u/i3Rq15Pedjtd7u+f98vXi1T/7gU8ft+aVA6mbkRC/F9YfOxmbreTT2eFfn7dTvfH17sAYNS+FLOy3r9uX66Xt1fJPqh1Mjep7/jr9uXz2v2g3J4q3SSH+XV7WVNbv073H+f79dR37HGr3uwm1Rd/3V7Ol+vl7duOM3OrdegnscGv29rQez09bvevQr2+7ZP3s+vc7eV6+XF6nN9Pb6JWvy0mCZMU8tft5fb2OImKobZII0xOMvp1e/m8P06X/hap8bMwqUn06/b1ervtf81WTDVOu/+30/307fwcafAcwiAm6bXphzgp//Pr9l0o7XCrhlPqdGbMfH7pW8bblGya3VieZkxvpkVtk/NkVjNPJfsfz0mJ/UNq5w3SMln58TT449LbaZVUlknZuWynf06mK3qYnKv263a5Zd3bR5+BN13YNtnM8eumDb1vEzc07U7Z0s+LPD5wK4FIszOSe3tyNqPpRoNMalT8uj0jv95Oq0HAk+U7v27vT5Gw6+Pl9OOpiWZ6m7Yb7D15tP5104c6cBuUkpmEs5s1MSKzrRihWcb461ZljHtbrZvYSRX2X7cjoUxuR2GQnRzN09vrVTK5nTRBdrJmrLPI0mI3WW0yz/S0KEUnuS1IIDf9kmVLTxD38XI/i7FEbVBKfvpFu3/7cnnZxTGuG+gw/Yqtxt7Ot7dfl/v5uVft4w/Xia5NKgYWy79+6Zuq6+StJgUeYFMvyONu4m+YDi/v2iTz1KUC7PTjvF2v5/vH91NficmdgHMZxzNhTt05OoW9OL1hV1u7Obxd53Oc3rlhT6z1XZ9Umt63G3NiDi931YZpegf/+HG6P/Ysvl1Si+bT7xi7XsTKENrS4mWSMjYG5fMLrUD8bM15b+95BO5ttgXoNH1Ygk0lSmjTTjw79mlncnfzbeKMJsdzFauP7+f7j9vzXb6fXi8nkS3iruWXJ+UCft3WtaY31GYlZuski6F10erj5rZMks30vpyT8Z2lNmvOZUzDtCVF6pbb0iSerUVvDYpft03Bs50cVt3be7n9+CKMts/PTi9f1ehOJpfbpZ/d9AtdDPLSG2vf5vm4oaAWEsbaGiU/vYsUY/KbtSVAfnpVXVOyWjqWW6kl9rMZ3rtYT1uWRzOH2v/44x/vl2fc8nb+x7/9+3/8z//8f3oS/bY="; \ No newline at end of file diff --git a/docs/assets/style.css b/docs/assets/style.css index 5ba5a2a9..44328e99 100644 --- a/docs/assets/style.css +++ b/docs/assets/style.css @@ -1595,9 +1595,9 @@ .container-main { grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax( - 0, - 20rem - ); + 0, + 20rem + ); grid-template-areas: "sidebar content toc"; } diff --git a/docs/classes/APIError.html b/docs/classes/APIError.html new file mode 100644 index 00000000..f7205d50 --- /dev/null +++ b/docs/classes/APIError.html @@ -0,0 +1,6 @@ +APIError | node-switchbot
node-switchbot
    Preparing search index...

    Class APIError

    Error thrown when API request fails

    +

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    Constructors

    Properties

    code?: string
    statusCode?: number
    statusMessage?: string
    diff --git a/docs/classes/APINotAvailableError.html b/docs/classes/APINotAvailableError.html new file mode 100644 index 00000000..2193b30b --- /dev/null +++ b/docs/classes/APINotAvailableError.html @@ -0,0 +1,4 @@ +APINotAvailableError | node-switchbot
    node-switchbot
      Preparing search index...

      Class APINotAvailableError

      Error thrown when API is not available or credentials are missing

      +

      Hierarchy (View Summary)

      Index

      Constructors

      Properties

      Constructors

      Properties

      code?: string
      diff --git a/docs/classes/Advertising.html b/docs/classes/Advertising.html deleted file mode 100644 index 6aaf4f40..00000000 --- a/docs/classes/Advertising.html +++ /dev/null @@ -1,21 +0,0 @@ -Advertising | node-switchbot
      node-switchbot
        Preparing search index...

        Class Advertising

        Represents the advertising data parser for SwitchBot devices.

        -
        Index

        Constructors

        Methods

        Constructors

        Methods

        • Parses the advertisement data coming from SwitchBot device.

          -

          This function processes advertising packets received from SwitchBot devices -and extracts relevant information based on the device type.

          -

          Parameters

          • peripheral: Peripheral

            The peripheral device object from noble.

            -
          • emitLog: (level: string, message: string) => void

            The function to emit log messages.

            -

          Returns Promise<null | ad>

            -
          • An object containing parsed data specific to the SwitchBot device type, or null if the device is not recognized.
          • -
          -
        • Parses the service data based on the device model.

          -

          Parameters

          • model: string

            The device model.

            -
          • serviceData: Buffer

            The service data buffer.

            -
          • manufacturerData: Buffer

            The manufacturer data buffer.

            -
          • emitLog: (level: string, message: string) => void

            The function to emit log messages.

            -

          Returns Promise<any>

            -
          • The parsed service data.
          • -
          -
        diff --git a/docs/classes/BLEConnection.html b/docs/classes/BLEConnection.html new file mode 100644 index 00000000..681e919e --- /dev/null +++ b/docs/classes/BLEConnection.html @@ -0,0 +1,25 @@ +BLEConnection | node-switchbot
        node-switchbot
          Preparing search index...

          Class BLEConnection

          BLE Connection for communicating with SwitchBot devices

          +
          Index

          Constructors

          • Parameters

            • options: { logger?: Logger; logLevel?: number; noble?: any } = {}

            Returns BLEConnection

          Methods

          • Parameters

            • mac: string

            Returns void

          • Connect to a device

            +

            Parameters

            • mac: string

            Returns Promise<void>

          • Disconnect from a device

            +

            Parameters

            • mac: string

            Returns Promise<void>

          • Disconnect all devices

            +

            Returns Promise<void>

          • Get connected device count

            +

            Returns number

          • Check if connected to device

            +

            Parameters

            • mac: string

            Returns boolean

          • Mark the next disconnect for this MAC as expected

            +

            Parameters

            • mac: string

            Returns void

          • Read data from device

            +

            Parameters

            • mac: string

            Returns Promise<Buffer<ArrayBufferLike>>

          • Parameters

            • mac: string
            • data: Buffer
            • options: {
                  expectNotification?: boolean;
                  expectResponse?: boolean;
                  notificationTimeoutMs?: number;
                  responseTimeoutMs?: number;
                  validateResponse?: boolean;
              } = {}

            Returns Promise<Buffer<ArrayBufferLike> | undefined>

          • Parameters

            • mac: string
            • keyHex: string
            • ivHex: string
            • mode: "auto" | "ctr" | "gcm" = 'auto'

            Returns void

          • Parameters

            • timeoutMs: number

            Returns void

          • Parameters

            • mac: string
            • handler: (payload: Buffer) => void

            Returns Promise<void>

          • Parameters

            • mac: string
            • handler: (payload: Buffer) => void

            Returns void

          • Write data to device

            +

            Parameters

            • mac: string
            • data: Buffer

            Returns Promise<void>

          diff --git a/docs/classes/BLENotAvailableError.html b/docs/classes/BLENotAvailableError.html new file mode 100644 index 00000000..07a95bc6 --- /dev/null +++ b/docs/classes/BLENotAvailableError.html @@ -0,0 +1,4 @@ +BLENotAvailableError | node-switchbot
          node-switchbot
            Preparing search index...

            Class BLENotAvailableError

            Error thrown when BLE is not available or supported

            +

            Hierarchy (View Summary)

            Index

            Constructors

            Properties

            Constructors

            Properties

            code?: string
            diff --git a/docs/classes/BLEScanner.html b/docs/classes/BLEScanner.html new file mode 100644 index 00000000..94b9280f --- /dev/null +++ b/docs/classes/BLEScanner.html @@ -0,0 +1,17 @@ +BLEScanner | node-switchbot
            node-switchbot
              Preparing search index...

              Class BLEScanner

              BLE Scanner for discovering SwitchBot devices

              +

              Hierarchy

              • EventEmitter
                • BLEScanner
              Index

              Constructors

              • Parameters

                • options: { logLevel?: number; noble?: any } = {}

                Returns BLEScanner

              Methods

              • Cleanup all resources

                +

                Returns void

              • Check if currently scanning

                +

                Returns boolean

              • Stop scanning

                +

                Returns void

              • Wait for specific device

                +

                Parameters

                • mac: string
                • timeoutMs: number = BLE_SCAN_TIMEOUT
                • OptionalbleId: string

                Returns Promise<BLEAdvertisement>

              diff --git a/docs/classes/CommandFailedError.html b/docs/classes/CommandFailedError.html new file mode 100644 index 00000000..5e77156d --- /dev/null +++ b/docs/classes/CommandFailedError.html @@ -0,0 +1,6 @@ +CommandFailedError | node-switchbot
              node-switchbot
                Preparing search index...

                Class CommandFailedError

                Error thrown when a command fails

                +

                Hierarchy (View Summary)

                Index

                Constructors

                Properties

                Constructors

                Properties

                code?: string
                connectionType?: "ble" | "api"
                originalError?: Error
                diff --git a/docs/classes/ConnectionTimeoutError.html b/docs/classes/ConnectionTimeoutError.html new file mode 100644 index 00000000..cb2a4da8 --- /dev/null +++ b/docs/classes/ConnectionTimeoutError.html @@ -0,0 +1,5 @@ +ConnectionTimeoutError | node-switchbot
                node-switchbot
                  Preparing search index...

                  Class ConnectionTimeoutError

                  Error thrown when a connection timeout occurs

                  +

                  Hierarchy (View Summary)

                  Index

                  Constructors

                  Properties

                  Constructors

                  Properties

                  code?: string
                  timeoutMs?: number
                  diff --git a/docs/classes/DeviceManager.html b/docs/classes/DeviceManager.html new file mode 100644 index 00000000..c7003d4b --- /dev/null +++ b/docs/classes/DeviceManager.html @@ -0,0 +1,25 @@ +DeviceManager | node-switchbot
                  node-switchbot
                    Preparing search index...

                    Class DeviceManager

                    Device Manager for managing multiple devices

                    +

                    Hierarchy

                    • EventEmitter
                      • DeviceManager
                    Index

                    Constructors

                    Methods

                    • Check if device exists

                      +

                      Parameters

                      • deviceId: string

                      Returns boolean

                    • Remove a device from the manager

                      +

                      Parameters

                      • deviceId: string

                      Returns boolean

                    diff --git a/docs/classes/DeviceNotFoundError.html b/docs/classes/DeviceNotFoundError.html new file mode 100644 index 00000000..7fffc46d --- /dev/null +++ b/docs/classes/DeviceNotFoundError.html @@ -0,0 +1,4 @@ +DeviceNotFoundError | node-switchbot
                    node-switchbot
                      Preparing search index...

                      Class DeviceNotFoundError

                      Error thrown when a device is not found

                      +

                      Hierarchy (View Summary)

                      Index

                      Constructors

                      Properties

                      Constructors

                      Properties

                      code?: string
                      diff --git a/docs/classes/DeviceOverrideStateDuringConnection.html b/docs/classes/DeviceOverrideStateDuringConnection.html new file mode 100644 index 00000000..b17c1be2 --- /dev/null +++ b/docs/classes/DeviceOverrideStateDuringConnection.html @@ -0,0 +1,82 @@ +DeviceOverrideStateDuringConnection | node-switchbot
                      node-switchbot
                        Preparing search index...

                        Class DeviceOverrideStateDuringConnectionAbstract

                        Base class for devices that should ignore advertisement state while connected. +Prevents stale BLE advertisement data from overriding active connection state.

                        +

                        Hierarchy (View Summary)

                        Index

                        Constructors

                        Accessors

                        • get deviceType(): string

                          Get device type (property accessor for convenience)

                          +

                          Returns string

                        • get id(): string | undefined

                          Get device ID (property accessor for convenience)

                          +

                          Returns string | undefined

                        • get mac(): string | undefined

                          Get MAC address (property accessor for convenience)

                          +

                          Returns string | undefined

                        • get name(): string

                          Get device name (property accessor for convenience)

                          +

                          Returns string

                        Methods

                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                          +

                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                          +

                          Returns a CommandResult object with device info fields.

                          +

                          Returns Promise<CommandResult>

                        • Returns true if device should be polled (passive polling interval elapsed)

                          +

                          Parameters

                          • interval: number = PASSIVE_POLL_INTERVAL

                          Returns boolean

                        • Register a custom fallback handler

                          +

                          Parameters

                          • handler: FallbackHandler
                          • Optionaloptions: FallbackHandlerOptions

                          Returns string

                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                          +

                          Parameters

                          • commands: (() => Promise<boolean>)[]

                          Returns Promise<boolean>

                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                          +

                          Parameters

                          • commands: (() => Promise<boolean>)[]

                          Returns Promise<boolean>

                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                          +

                          Parameters

                          • mode: string | number

                            Mode value (number or string, per-device enum recommended)

                            +

                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                            +

                            Returns a CommandResult object indicating success and mode info.

                            +

                          Returns Promise<CommandResult>

                        diff --git a/docs/classes/DiscoveryError.html b/docs/classes/DiscoveryError.html new file mode 100644 index 00000000..72b0df3d --- /dev/null +++ b/docs/classes/DiscoveryError.html @@ -0,0 +1,5 @@ +DiscoveryError | node-switchbot
                        node-switchbot
                          Preparing search index...

                          Class DiscoveryError

                          Error thrown when device discovery fails

                          +

                          Hierarchy (View Summary)

                          Index

                          Constructors

                          Properties

                          Constructors

                          Properties

                          code?: string
                          originalError?: Error
                          diff --git a/docs/classes/ErrorUtils.html b/docs/classes/ErrorUtils.html deleted file mode 100644 index 6065e94a..00000000 --- a/docs/classes/ErrorUtils.html +++ /dev/null @@ -1,25 +0,0 @@ -ErrorUtils | node-switchbot
                          node-switchbot
                            Preparing search index...

                            Class ErrorUtils

                            Enhanced error handling utilities.

                            -
                            Index

                            Constructors

                            Methods

                            • Creates a command error with context.

                              -

                              Parameters

                              • command: string

                                The command that failed

                                -
                              • deviceId: string

                                The device ID

                                -
                              • Optionalcause: Error

                                The underlying cause

                                -

                              Returns Error

                              A descriptive command error

                              -
                            • Creates a connection error with context.

                              -

                              Parameters

                              • deviceId: string

                                The device ID that failed to connect

                                -
                              • Optionalcause: Error

                                The underlying cause of the connection failure

                                -

                              Returns Error

                              A descriptive connection error

                              -
                            • Creates a timeout error with context.

                              -

                              Parameters

                              • operation: string

                                The operation that timed out

                                -
                              • timeoutMs: number

                                The timeout duration in milliseconds

                                -

                              Returns Error

                              A descriptive timeout error

                              -
                            • Wraps an async operation with timeout and enhanced error handling.

                              -

                              Type Parameters

                              • T

                              Parameters

                              • operation: Promise<T>

                                The async operation to wrap

                                -
                              • timeoutMs: number

                                Timeout in milliseconds

                                -
                              • operationName: string

                                Name of the operation for error messages

                                -

                              Returns Promise<T>

                              Promise that resolves with the operation result or rejects with timeout

                              -
                            diff --git a/docs/classes/OpenAPIClient.html b/docs/classes/OpenAPIClient.html new file mode 100644 index 00000000..7fc19c46 --- /dev/null +++ b/docs/classes/OpenAPIClient.html @@ -0,0 +1,66 @@ +OpenAPIClient | node-switchbot
                            node-switchbot
                              Preparing search index...

                              Class OpenAPIClient

                              OpenAPI Client for SwitchBot API v1.1

                              +
                              Index

                              Constructors

                              • Parameters

                                • token: string
                                • secret: string
                                • baseURL: string = urls.base
                                • OptionallogLevel: number

                                Returns OpenAPIClient

                              Methods

                              • Parameters

                                • deviceId: string
                                • mode: "auto" | "manual" | "sleep"

                                Returns Promise<APICommandResponse>

                              • Parameters

                                • deviceId: string
                                • position: number
                                • speed: number = 255

                                Returns Promise<APICommandResponse>

                              • Delete webhook

                                +

                                Parameters

                                • url: string

                                Returns Promise<void>

                              • Execute a scene

                                +

                                Parameters

                                • sceneId: string

                                Returns Promise<void>

                              • Get client configuration

                                +

                                Returns { baseURL: string; token: string }

                              • Get specific device information

                                +

                                Parameters

                                • deviceId: string

                                Returns Promise<APIDevice | undefined>

                              • Get devices by type

                                +

                                Parameters

                                • deviceType: string

                                Returns Promise<APIDevice[]>

                              • Check if device has cloud service enabled

                                +

                                Parameters

                                • deviceId: string

                                Returns Promise<boolean>

                              • Parameters

                                • deviceId: string
                                • red: number
                                • green: number
                                • blue: number

                                Returns Promise<APICommandResponse>

                              • Send command to device

                                +

                                Parameters

                                • deviceId: string
                                • command: string
                                • Optionalparameter: any

                                Returns Promise<APICommandResponse>

                              • Update base URL

                                +

                                Parameters

                                • newBaseURL: string

                                Returns void

                              diff --git a/docs/classes/ParameterChecker.html b/docs/classes/ParameterChecker.html deleted file mode 100644 index 523c72d3..00000000 --- a/docs/classes/ParameterChecker.html +++ /dev/null @@ -1,69 +0,0 @@ -ParameterChecker | node-switchbot
                              node-switchbot
                                Preparing search index...

                                Class ParameterChecker

                                Hierarchy

                                • EventEmitter
                                  • ParameterChecker
                                Index

                                Constructors

                                • Parameters

                                  • Optionaloptions: EventEmitterOptions

                                  Returns ParameterChecker

                                Accessors

                                Methods

                                • Checks if the specified object contains valid values based on the provided rules.

                                  -

                                  Parameters

                                  • obj: Record<string, unknown>

                                    Object including parameters you want to check.

                                    -
                                  • rules: Record<string, Rule>

                                    Object including rules for the parameters.

                                    -
                                  • Optionalrequired: boolean = false

                                    Flag whether the obj is required or not.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is an array.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is a boolean.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is a float.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is an integer.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is an object.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                • Checks if the value is specified (not undefined).

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -

                                  Returns boolean

                                    -
                                  • True if the value is specified, false otherwise.
                                  • -
                                  -
                                • Checks if the value is a string.

                                  -

                                  Parameters

                                  • value: unknown

                                    The value to check.

                                    -
                                  • rule: Rule

                                    The rule object containing validation criteria.

                                    -
                                  • Optionalname: string = 'value'

                                    The parameter name.

                                    -

                                  Returns Promise<boolean>

                                    -
                                  • Resolves to true if the value is valid, false otherwise.
                                  • -
                                  -
                                diff --git a/docs/classes/SequenceDevice.html b/docs/classes/SequenceDevice.html new file mode 100644 index 00000000..8a201620 --- /dev/null +++ b/docs/classes/SequenceDevice.html @@ -0,0 +1,92 @@ +SequenceDevice | node-switchbot
                                node-switchbot
                                  Preparing search index...

                                  Class SequenceDeviceAbstract

                                  Base class for devices that expose an advertisement sequence number. +Automatically triggers a status refresh when the sequence number changes.

                                  + +

                                  Subclasses should implement their getStatus() using the centralized +getStatusWithFallback() method from SwitchBotDevice for robust BLE-first, +API-fallback logic. See SwitchBotDevice for details.

                                  +

                                  Example:

                                  +
                                  async getStatus(): Promise<DeviceStatus> {
                                  return this.getStatusWithFallback(
                                  bleData => ({ ... }),
                                  apiData => ({ ... })
                                  )
                                  } +
                                  + +

                                  Hierarchy (View Summary)

                                  Index

                                  Constructors

                                  • Parameters

                                    • info: DeviceInfo
                                    • options: {
                                          apiClient?: OpenAPIClient;
                                          bleConnection?: BLEConnection;
                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                          enableCircuitBreaker?: boolean;
                                          enableConnectionIntelligence?: boolean;
                                          enableFallback?: boolean;
                                          enableRetry?: boolean;
                                          logLevel?: number;
                                          preferredConnection?: ConnectionType;
                                          retryConfig?: RetryConfig;
                                      } = {}

                                    Returns SequenceDevice

                                  Accessors

                                  • get deviceType(): string

                                    Get device type (property accessor for convenience)

                                    +

                                    Returns string

                                  • get id(): string | undefined

                                    Get device ID (property accessor for convenience)

                                    +

                                    Returns string | undefined

                                  • get mac(): string | undefined

                                    Get MAC address (property accessor for convenience)

                                    +

                                    Returns string | undefined

                                  • get name(): string

                                    Get device name (property accessor for convenience)

                                    +

                                    Returns string

                                  Methods

                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                    +

                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                    +

                                    Returns a CommandResult object with device info fields.

                                    +

                                    Returns Promise<CommandResult>

                                  • Returns true if device should be polled (passive polling interval elapsed)

                                    +

                                    Parameters

                                    • interval: number = PASSIVE_POLL_INTERVAL

                                    Returns boolean

                                  • Register a custom fallback handler

                                    +

                                    Parameters

                                    • handler: FallbackHandler
                                    • Optionaloptions: FallbackHandlerOptions

                                    Returns string

                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                    +

                                    Parameters

                                    • commands: (() => Promise<boolean>)[]

                                    Returns Promise<boolean>

                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                    +

                                    Parameters

                                    • commands: (() => Promise<boolean>)[]

                                    Returns Promise<boolean>

                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                    +

                                    Parameters

                                    • mode: string | number

                                      Mode value (number or string, per-device enum recommended)

                                      +

                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                      +

                                      Returns a CommandResult object indicating success and mode info.

                                      +

                                    Returns Promise<CommandResult>

                                  diff --git a/docs/classes/SwitchBot.html b/docs/classes/SwitchBot.html new file mode 100644 index 00000000..2e7c317d --- /dev/null +++ b/docs/classes/SwitchBot.html @@ -0,0 +1,22 @@ +SwitchBot | node-switchbot
                                  node-switchbot
                                    Preparing search index...

                                    Class SwitchBot

                                    Main SwitchBot class - Hybrid BLE/API with automatic fallback

                                    +

                                    Hierarchy

                                    • EventEmitter
                                      • SwitchBot
                                    Index

                                    Constructors

                                    Accessors

                                    Methods

                                    • Cleanup and disconnect

                                      +

                                      Returns Promise<void>

                                    • Check if API is available

                                      +

                                      Returns boolean

                                    • Check if BLE is available

                                      +

                                      Returns boolean

                                    diff --git a/docs/classes/SwitchBotBLE.html b/docs/classes/SwitchBotBLE.html deleted file mode 100644 index 5a497a44..00000000 --- a/docs/classes/SwitchBotBLE.html +++ /dev/null @@ -1,39 +0,0 @@ -SwitchBotBLE | node-switchbot
                                    node-switchbot
                                      Preparing search index...

                                      Class SwitchBotBLE

                                      SwitchBotBLE class to interact with SwitchBot devices.

                                      -

                                      Hierarchy

                                      • EventEmitter
                                        • SwitchBotBLE
                                      Index

                                      Constructors

                                      Properties

                                      noble: any
                                      nobleInitialized: Promise<void>
                                      onadvertisement?: onadvertisement
                                      ondiscover?: ondiscover

                                      Methods

                                      • Starts scanning for SwitchBot devices.

                                        -

                                        Parameters

                                        • Optionalparams: Params = {}

                                          Optional parameters.

                                          -

                                        Returns Promise<void>

                                          -
                                        • Resolves when scanning starts successfully.
                                        • -
                                        -
                                      • Stops scanning for SwitchBot devices.

                                        -

                                        Returns Promise<void>

                                          -
                                        • Resolves when scanning stops successfully.
                                        • -
                                        -
                                      • Validates the parameters.

                                        -

                                        Parameters

                                        • params: Params

                                          The parameters to validate.

                                          -
                                        • schema: Record<string, unknown>

                                          The schema to validate against.

                                          -

                                        Returns Promise<void>

                                          -
                                        • Resolves if parameters are valid, otherwise throws an error.
                                        • -
                                        -
                                      • Waits for the specified time.

                                        -

                                        Parameters

                                        • msec: number

                                          The time to wait in milliseconds.

                                          -

                                        Returns Promise<void>

                                          -
                                        • Resolves after the specified time.
                                        • -
                                        -
                                      diff --git a/docs/classes/SwitchBotError.html b/docs/classes/SwitchBotError.html new file mode 100644 index 00000000..2de6b53e --- /dev/null +++ b/docs/classes/SwitchBotError.html @@ -0,0 +1,4 @@ +SwitchBotError | node-switchbot
                                      node-switchbot
                                        Preparing search index...

                                        Class SwitchBotError

                                        Base error class for SwitchBot errors

                                        +

                                        Hierarchy (View Summary)

                                        Index

                                        Constructors

                                        Properties

                                        Constructors

                                        Properties

                                        code?: string
                                        diff --git a/docs/classes/SwitchBotOpenAPI.html b/docs/classes/SwitchBotOpenAPI.html deleted file mode 100644 index 0b602cea..00000000 --- a/docs/classes/SwitchBotOpenAPI.html +++ /dev/null @@ -1,57 +0,0 @@ -SwitchBotOpenAPI | node-switchbot
                                        node-switchbot
                                          Preparing search index...

                                          Class SwitchBotOpenAPI

                                          The SwitchBotOpenAPI class provides methods to interact with the SwitchBot OpenAPI. -It allows you to retrieve device information, control devices, and manage webhooks.

                                          -
                                          const switchBotAPI = new SwitchBotOpenAPI('your-token', 'your-secret');

                                          // Get devices
                                          switchBotAPI.getDevices().then(response => {
                                          console.log(response);
                                          }).catch(error => {
                                          console.error(error);
                                          });

                                          // Control a device
                                          switchBotAPI.controlDevice('device-id', 'turnOn', 'default').then(response => {
                                          console.log(response);
                                          }).catch(error => {
                                          console.error(error);
                                          });

                                          // Setup webhook
                                          switchBotAPI.setupWebhook('http://your-webhook-url').then(() => {
                                          console.log('Webhook setup successfully');
                                          }).catch(error => {
                                          console.error(error);
                                          }); -
                                          - -

                                          The API token used for authentication.

                                          -

                                          The secret key used for signing requests.

                                          -

                                          Hierarchy

                                          • EventEmitter
                                            • SwitchBotOpenAPI
                                          Index

                                          Constructors

                                          • Creates an instance of the SwitchBot OpenAPI client.

                                            -

                                            Parameters

                                            • token: string

                                              The API token used for authentication.

                                              -
                                            • secret: string

                                              The secret key used for signing requests.

                                              -
                                            • Optionalhostname: string

                                            Returns SwitchBotOpenAPI

                                          Properties

                                          webhookEventListener?:
                                              | null
                                              | Server<typeof IncomingMessage, typeof ServerResponse> = null

                                          Methods

                                          • Controls a device by sending a command to the SwitchBot API.

                                            -

                                            Parameters

                                            • deviceId: string

                                              The ID of the device to control.

                                              -
                                            • command: string

                                              The command to send to the device.

                                              -
                                            • parameter: string

                                              The parameter for the command.

                                              -
                                            • commandType: commandType = 'command'

                                              The type of the command (default is 'command').

                                              -
                                            • Optionaltoken: string

                                              (Optional) The token used for authentication. If not provided, the instance token will be used.

                                              -
                                            • Optionalsecret: string

                                              (Optional) The secret used for authentication. If not provided, the instance secret will be used.

                                              -

                                            Returns Promise<{ response: pushResponseBody; statusCode: number }>

                                            A promise that resolves to an object containing the response body and status code.

                                            -

                                            An error if the device control fails.

                                            -
                                          • Deletes a webhook by sending a request to the specified URL.

                                            -

                                            Parameters

                                            • url: string

                                              The URL of the webhook to be deleted.

                                              -
                                            • Optionaltoken: string

                                              (Optional) The token used for authentication. If not provided, the instance token will be used.

                                              -
                                            • Optionalsecret: string

                                              (Optional) The secret used for authentication. If not provided, the instance secret will be used.

                                              -

                                            Returns Promise<void>

                                            A promise that resolves when the webhook is successfully deleted.

                                            -

                                            Will log an error if the deletion fails.

                                            -
                                          • Retrieves the list of devices from the SwitchBot OpenAPI.

                                            -

                                            Parameters

                                            • Optionaltoken: string

                                              (Optional) The token used for authentication. If not provided, the instance token will be used.

                                              -
                                            • Optionalsecret: string

                                              (Optional) The secret used for authentication. If not provided, the instance secret will be used.

                                              -

                                            Returns Promise<{ response: devices; statusCode: number }>

                                            A promise that resolves to an object containing the API response.

                                            -

                                            Throws an error if the request to get devices fails.

                                            -
                                          • Retrieves the status of a specific device.

                                            -

                                            Parameters

                                            • deviceId: string

                                              The unique identifier of the device.

                                              -
                                            • Optionaltoken: string

                                              (Optional) The token used for authentication. If not provided, the instance token will be used.

                                              -
                                            • Optionalsecret: string

                                              (Optional) The secret used for authentication. If not provided, the instance secret will be used.

                                              -

                                            Returns Promise<{ response: deviceStatus; statusCode: number }>

                                            A promise that resolves to an object containing the device status and the status code of the request.

                                            -

                                            An error if the request fails.

                                            -
                                          • Sets up a webhook listener and configures the webhook on the server.

                                            -

                                            This method performs the following steps:

                                            -
                                              -
                                            1. Creates a local server to listen for incoming webhook events.
                                            2. -
                                            3. Sends a request to set up the webhook with the provided URL.
                                            4. -
                                            5. Sends a request to update the webhook configuration.
                                            6. -
                                            7. Sends a request to query the current webhook URL.
                                            8. -
                                            -

                                            Parameters

                                            • url: string

                                              The URL to which the webhook events will be sent.

                                              -
                                            • Optionaltoken: string

                                              (Optional) The token used for authentication. If not provided, the instance token will be used.

                                              -
                                            • Optionalsecret: string

                                              (Optional) The secret used for authentication. If not provided, the instance secret will be used.

                                              -

                                            Returns Promise<void>

                                            A promise that resolves when the webhook setup is complete.

                                            -

                                            Will log an error if any step in the webhook setup process fails.

                                            -
                                          diff --git a/docs/classes/SwitchbotDevice.html b/docs/classes/SwitchbotDevice.html index ef08ec05..09b27e1a 100644 --- a/docs/classes/SwitchbotDevice.html +++ b/docs/classes/SwitchbotDevice.html @@ -1,47 +1,115 @@ -SwitchbotDevice | node-switchbot
                                          node-switchbot
                                            Preparing search index...

                                            Class SwitchbotDevice

                                            Represents a Switchbot Device.

                                            -

                                            Hierarchy (View Summary)

                                            Index

                                            Constructors

                                            Accessors

                                            address -connectionState -friendlyName +SwitchBotDevice | node-switchbot
                                            node-switchbot
                                              Preparing search index...

                                              Class SwitchBotDeviceAbstract

                                              Base class for all SwitchBot devices

                                              + +

                                              This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                              +
                                                +
                                              • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                              • +
                                              • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                              • +
                                              • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                              • +
                                              • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                              • +
                                              + +
                                                +
                                              • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                              • +
                                              • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                              • +
                                              • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                              • +
                                              + +
                                              async getStatus(): Promise<DeviceStatus> {
                                              return this.getStatusWithFallback(
                                              bleData => ({ ... }), // normalize BLE data
                                              apiData => ({ ... }), // normalize API data
                                              )
                                              }

                                              async turnOn(): Promise<boolean> {
                                              const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                              return result.success
                                              } +
                                              + + +
                                                +
                                              • preferredConnection: 'ble' | 'api' (default: 'ble')
                                              • +
                                              • enableFallback: boolean (default: true)
                                              • +
                                              • enableConnectionIntelligence: boolean (default: true)
                                              • +
                                              • enableCircuitBreaker: boolean (default: true)
                                              • +
                                              • enableRetry: boolean (default: true)
                                              • +
                                              + +
                                                +
                                              • getStatusWithFallback()
                                              • +
                                              • sendCommand()
                                              • +
                                              • hasBLE(), hasAPI()
                                              • +
                                              • setPreferredConnection(), setFallbackEnabled()
                                              • +
                                              +

                                              This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                              +

                                              Hierarchy (View Summary)

                                              Index

                                              Constructors

                                              • Initializes a new instance of the SwitchbotDevice class.

                                                -

                                                Parameters

                                                • peripheral: Peripheral

                                                  The peripheral object from noble.

                                                  -
                                                • noble: Noble

                                                  The Noble object.

                                                  -

                                                Returns SwitchbotDevice

                                              Accessors

                                              • get onConnectHandler(): () => Promise<void>

                                                Returns () => Promise<void>

                                              • set onConnectHandler(func: () => Promise<void>): void

                                                Parameters

                                                • func: () => Promise<void>

                                                Returns void

                                              • get onDisconnectHandler(): () => Promise<void>

                                                Returns () => Promise<void>

                                              • set onDisconnectHandler(func: () => Promise<void>): void

                                                Parameters

                                                • func: () => Promise<void>

                                                Returns void

                                              Methods

                                              • Sends a command to the device and awaits a response.

                                                -

                                                Parameters

                                                • reqBuf: Buffer

                                                  The command buffer.

                                                  -

                                                Returns Promise<Buffer<ArrayBufferLike>>

                                                A Promise that resolves with the response buffer.

                                                -
                                              • Connects to the device.

                                                -

                                                Returns Promise<void>

                                                A Promise that resolves when the connection is complete.

                                                -
                                              • Disconnects from the device.

                                                -

                                                Returns Promise<void>

                                                A Promise that resolves when the disconnection is complete.

                                                -
                                              • Discovers the device services.

                                                -

                                                Returns Promise<Service[]>

                                                A Promise that resolves with the list of services.

                                                -
                                              • Retrieves the device characteristics.

                                                -

                                                Returns Promise<Chars>

                                                A Promise that resolves with the device characteristics.

                                                -
                                              • Retrieves the device name.

                                                -

                                                Returns Promise<string>

                                                A Promise that resolves with the device name.

                                                -
                                              • Internal method to handle the connection process.

                                                -

                                                Returns Promise<void>

                                                A Promise that resolves when the connection is complete.

                                                -
                                              • Logs a message with the specified log level.

                                                -

                                                Parameters

                                                • level: string

                                                  The severity level of the log (e.g., 'info', 'warn', 'error').

                                                  -
                                                • message: string

                                                  The log message to be emitted.

                                                  -

                                                Returns Promise<void>

                                              • Sets the device name.

                                                -

                                                Parameters

                                                • name: string

                                                  The new device name.

                                                  -

                                                Returns Promise<void>

                                                A Promise that resolves when the name is set.

                                                -
                                              • Unsubscribes from the notify characteristic.

                                                -

                                                Returns Promise<void>

                                                A Promise that resolves when the unsubscription is complete.

                                                -
                                              +mac +name +

                                              Methods

                                              Constructors

                                              • Parameters

                                                • info: DeviceInfo
                                                • options: {
                                                      apiClient?: OpenAPIClient;
                                                      bleConnection?: BLEConnection;
                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                      enableCircuitBreaker?: boolean;
                                                      enableConnectionIntelligence?: boolean;
                                                      enableFallback?: boolean;
                                                      enableRetry?: boolean;
                                                      logLevel?: number;
                                                      preferredConnection?: ConnectionType;
                                                      retryConfig?: RetryConfig;
                                                  } = {}

                                                Returns SwitchBotDevice

                                              Accessors

                                              • get deviceType(): string

                                                Get device type (property accessor for convenience)

                                                +

                                                Returns string

                                              • get id(): string | undefined

                                                Get device ID (property accessor for convenience)

                                                +

                                                Returns string | undefined

                                              • get mac(): string | undefined

                                                Get MAC address (property accessor for convenience)

                                                +

                                                Returns string | undefined

                                              • get name(): string

                                                Get device name (property accessor for convenience)

                                                +

                                                Returns string

                                              Methods

                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                +

                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                +

                                                Returns a CommandResult object with device info fields.

                                                +

                                                Returns Promise<CommandResult>

                                              • Get circuit breaker for API

                                                +

                                                Returns CircuitBreaker

                                              • Get circuit breaker for BLE

                                                +

                                                Returns CircuitBreaker

                                              • Get connection tracker for this device

                                                +

                                                Returns ConnectionTracker

                                              • Get fallback handler manager

                                                +

                                                Returns FallbackHandlerManager

                                              • Get MAC address (if available)

                                                +

                                                Returns string | undefined

                                              • Check if API is available for this device

                                                +

                                                Returns boolean

                                              • Check if BLE is available for this device

                                                +

                                                Returns boolean

                                              • Poll device status if needed (passive polling)

                                                +

                                                Parameters

                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                Returns Promise<DeviceStatus | undefined>

                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                +

                                                Parameters

                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                Returns boolean

                                              • Register a custom fallback handler

                                                +

                                                Parameters

                                                • handler: FallbackHandler
                                                • Optionaloptions: FallbackHandlerOptions

                                                Returns string

                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                +

                                                Parameters

                                                • commands: (() => Promise<boolean>)[]

                                                Returns Promise<boolean>

                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                +

                                                Parameters

                                                • commands: (() => Promise<boolean>)[]

                                                Returns Promise<boolean>

                                              • Enable or disable circuit breaker

                                                +

                                                Parameters

                                                • enabled: boolean

                                                Returns void

                                              • Enable or disable connection intelligence

                                                +

                                                Parameters

                                                • enabled: boolean

                                                Returns void

                                              • Enable or disable fallback

                                                +

                                                Parameters

                                                • enabled: boolean

                                                Returns void

                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                +

                                                Parameters

                                                • mode: string | number

                                                  Mode value (number or string, per-device enum recommended)

                                                  +

                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                  +

                                                  Returns a CommandResult object indicating success and mode info.

                                                  +

                                                Returns Promise<CommandResult>

                                              • Enable or disable retry logic

                                                +

                                                Parameters

                                                • enabled: boolean

                                                Returns void

                                              • Unregister a fallback handler

                                                +

                                                Parameters

                                                • id: string

                                                Returns boolean

                                              diff --git a/docs/classes/ValidationError.html b/docs/classes/ValidationError.html new file mode 100644 index 00000000..75e8b6b8 --- /dev/null +++ b/docs/classes/ValidationError.html @@ -0,0 +1,5 @@ +ValidationError | node-switchbot
                                              node-switchbot
                                                Preparing search index...

                                                Class ValidationError

                                                Error thrown when invalid parameters are provided

                                                +

                                                Hierarchy (View Summary)

                                                Index

                                                Constructors

                                                Properties

                                                Constructors

                                                Properties

                                                code?: string
                                                parameter?: string
                                                diff --git a/docs/classes/ValidationUtils.html b/docs/classes/ValidationUtils.html deleted file mode 100644 index a0c68938..00000000 --- a/docs/classes/ValidationUtils.html +++ /dev/null @@ -1,51 +0,0 @@ -ValidationUtils | node-switchbot
                                                node-switchbot
                                                  Preparing search index...

                                                  Class ValidationUtils

                                                  Utility class for comprehensive input validation with improved error messages.

                                                  -
                                                  Index

                                                  Constructors

                                                  Methods

                                                  • Validates buffer and throws descriptive error.

                                                    -

                                                    Parameters

                                                    • buffer: any

                                                      The buffer to validate

                                                      -
                                                    • OptionalexpectedLength: number

                                                      Optional expected length

                                                      -
                                                    • paramName: string = 'buffer'

                                                      The parameter name for error reporting

                                                      -

                                                    Returns asserts buffer is Buffer<ArrayBufferLike>

                                                    When buffer is not a Buffer

                                                    -

                                                    When buffer length doesn't match expected

                                                    -
                                                  • Validates that a value is one of the allowed enum values.

                                                    -

                                                    Type Parameters

                                                    • T

                                                    Parameters

                                                    • value: any

                                                      The value to validate

                                                      -
                                                    • allowedValues: readonly T[]

                                                      Array of allowed values

                                                      -
                                                    • paramName: string = 'value'

                                                      The parameter name for error reporting

                                                      -

                                                    Returns asserts value is T

                                                    When value is not in allowed values

                                                    -
                                                  • Validates MAC address format.

                                                    -

                                                    Parameters

                                                    • address: any

                                                      The MAC address to validate

                                                      -
                                                    • paramName: string = 'address'

                                                      The parameter name for error reporting

                                                      -

                                                    Returns asserts address is string

                                                    When address is not a string

                                                    -

                                                    When address format is invalid

                                                    -
                                                  • Validates percentage value (0-100).

                                                    -

                                                    Parameters

                                                    • value: number

                                                      The value to validate

                                                      -
                                                    • paramName: string = 'value'

                                                      The parameter name for error reporting

                                                      -

                                                    Returns void

                                                    When value is not within valid range

                                                    -

                                                    When value is not a number

                                                    -
                                                  • Validates numeric range with enhanced checks.

                                                    -

                                                    Parameters

                                                    • value: number

                                                      The value to validate

                                                      -
                                                    • min: number

                                                      Minimum allowed value

                                                      -
                                                    • max: number

                                                      Maximum allowed value

                                                      -
                                                    • paramName: string = 'value'

                                                      The parameter name for error reporting

                                                      -
                                                    • mustBeInteger: boolean = false

                                                      Whether the value must be an integer

                                                      -

                                                    Returns void

                                                    When value is not a number

                                                    -

                                                    When value is outside valid range

                                                    -
                                                  • Validates RGB color value (0-255).

                                                    -

                                                    Parameters

                                                    • value: number

                                                      The color value to validate

                                                      -
                                                    • colorName: string = 'color'

                                                      The color name for error reporting

                                                      -

                                                    Returns void

                                                    When value is not within valid range

                                                    -

                                                    When value is not a number

                                                    -
                                                  • Validates string input with comprehensive checks.

                                                    -

                                                    Parameters

                                                    • value: any

                                                      The value to validate

                                                      -
                                                    • paramName: string = 'value'

                                                      The parameter name for error reporting

                                                      -
                                                    • minLength: number = 1

                                                      Minimum required length

                                                      -
                                                    • OptionalmaxLength: number

                                                      Optional maximum length

                                                      -

                                                    Returns asserts value is string

                                                    When value is not a string

                                                    -

                                                    When string length is invalid

                                                    -
                                                  diff --git a/docs/classes/WoAIHub.html b/docs/classes/WoAIHub.html new file mode 100644 index 00000000..0387765f --- /dev/null +++ b/docs/classes/WoAIHub.html @@ -0,0 +1,116 @@ +WoAIHub | node-switchbot
                                                  node-switchbot
                                                    Preparing search index...

                                                    Class WoAIHub

                                                    Base class for all SwitchBot devices

                                                    + +

                                                    This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                    +
                                                      +
                                                    • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                    • +
                                                    • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                    • +
                                                    • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                    • +
                                                    • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                    • +
                                                    + +
                                                      +
                                                    • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                    • +
                                                    • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                    • +
                                                    • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                    • +
                                                    + +
                                                    async getStatus(): Promise<DeviceStatus> {
                                                    return this.getStatusWithFallback(
                                                    bleData => ({ ... }), // normalize BLE data
                                                    apiData => ({ ... }), // normalize API data
                                                    )
                                                    }

                                                    async turnOn(): Promise<boolean> {
                                                    const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                    return result.success
                                                    } +
                                                    + + +
                                                      +
                                                    • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                    • +
                                                    • enableFallback: boolean (default: true)
                                                    • +
                                                    • enableConnectionIntelligence: boolean (default: true)
                                                    • +
                                                    • enableCircuitBreaker: boolean (default: true)
                                                    • +
                                                    • enableRetry: boolean (default: true)
                                                    • +
                                                    + +
                                                      +
                                                    • getStatusWithFallback()
                                                    • +
                                                    • sendCommand()
                                                    • +
                                                    • hasBLE(), hasAPI()
                                                    • +
                                                    • setPreferredConnection(), setFallbackEnabled()
                                                    • +
                                                    +

                                                    This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                    +

                                                    Hierarchy (View Summary)

                                                    Index

                                                    Constructors

                                                    • Parameters

                                                      • info: DeviceInfo
                                                      • options: {
                                                            apiClient?: OpenAPIClient;
                                                            bleConnection?: BLEConnection;
                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                            enableCircuitBreaker?: boolean;
                                                            enableConnectionIntelligence?: boolean;
                                                            enableFallback?: boolean;
                                                            enableRetry?: boolean;
                                                            logLevel?: number;
                                                            preferredConnection?: ConnectionType;
                                                            retryConfig?: RetryConfig;
                                                        } = {}

                                                      Returns WoAIHub

                                                    Accessors

                                                    • get deviceType(): string

                                                      Get device type (property accessor for convenience)

                                                      +

                                                      Returns string

                                                    • get id(): string | undefined

                                                      Get device ID (property accessor for convenience)

                                                      +

                                                      Returns string | undefined

                                                    • get mac(): string | undefined

                                                      Get MAC address (property accessor for convenience)

                                                      +

                                                      Returns string | undefined

                                                    • get name(): string

                                                      Get device name (property accessor for convenience)

                                                      +

                                                      Returns string

                                                    Methods

                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                      +

                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                      +

                                                      Returns a CommandResult object with device info fields.

                                                      +

                                                      Returns Promise<CommandResult>

                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                      +

                                                      Parameters

                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                      Returns boolean

                                                    • Register a custom fallback handler

                                                      +

                                                      Parameters

                                                      • handler: FallbackHandler
                                                      • Optionaloptions: FallbackHandlerOptions

                                                      Returns string

                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                      +

                                                      Parameters

                                                      • commands: (() => Promise<boolean>)[]

                                                      Returns Promise<boolean>

                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                      +

                                                      Parameters

                                                      • commands: (() => Promise<boolean>)[]

                                                      Returns Promise<boolean>

                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                      +

                                                      Parameters

                                                      • mode: string | number

                                                        Mode value (number or string, per-device enum recommended)

                                                        +

                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                        +

                                                        Returns a CommandResult object indicating success and mode info.

                                                        +

                                                      Returns Promise<CommandResult>

                                                    diff --git a/docs/classes/WoAirPurifier.html b/docs/classes/WoAirPurifier.html index 7a932439..2393f903 100644 --- a/docs/classes/WoAirPurifier.html +++ b/docs/classes/WoAirPurifier.html @@ -1,83 +1,88 @@ -WoAirPurifier | node-switchbot
                                                    node-switchbot
                                                      Preparing search index...

                                                      Class WoAirPurifier

                                                      Class representing a SwitchBot Air Purifier device.

                                                      -

                                                      Hierarchy (View Summary)

                                                      Index

                                                      Constructors

                                                      Accessors

                                                      address -connectionState -friendlyName +WoAirPurifier | node-switchbot
                                                      node-switchbot
                                                        Preparing search index...

                                                        Class WoAirPurifier

                                                        Air Purifier Device

                                                        +

                                                        Hierarchy (View Summary)

                                                        Implements

                                                        Index

                                                        Constructors

                                                        Accessors

                                                        • get address(): string

                                                          Returns string

                                                        • get connectionState(): string

                                                          Returns string

                                                        • get id(): string

                                                          Returns string

                                                        • get onConnectHandler(): () => Promise<void>

                                                          Returns () => Promise<void>

                                                        • set onConnectHandler(func: () => Promise<void>): void

                                                          Parameters

                                                          • func: () => Promise<void>

                                                          Returns void

                                                        • get onDisconnectHandler(): () => Promise<void>

                                                          Returns () => Promise<void>

                                                        • set onDisconnectHandler(func: () => Promise<void>): void

                                                          Parameters

                                                          • func: () => Promise<void>

                                                          Returns void

                                                        Methods

                                                        • Sends a command to the device and awaits a response.

                                                          -

                                                          Parameters

                                                          • reqBuf: Buffer

                                                            The command buffer.

                                                            -

                                                          Returns Promise<Buffer<ArrayBufferLike>>

                                                          A Promise that resolves with the response buffer.

                                                          -
                                                        • Internal method to handle the connection process.

                                                          -

                                                          Returns Promise<void>

                                                          A Promise that resolves when the connection is complete.

                                                          -
                                                        • Logs a message with the specified log level.

                                                          -

                                                          Parameters

                                                          • level: string

                                                            The severity level of the log (e.g., 'info', 'warn', 'error').

                                                            -
                                                          • message: string

                                                            The log message to be emitted.

                                                            -

                                                          Returns Promise<void>

                                                        • Operates the air purifier with the given byte array.

                                                          -

                                                          Parameters

                                                          • bytes: number[]

                                                            The byte array to send.

                                                            -

                                                          Returns Promise<boolean>

                                                            -
                                                          • Resolves with true if the operation was successful.
                                                          • -
                                                          -
                                                        • Sets the device name.

                                                          -

                                                          Parameters

                                                          • name: string

                                                            The new device name.

                                                            -

                                                          Returns Promise<void>

                                                          A Promise that resolves when the name is set.

                                                          -
                                                        • Sets the mode of the air purifier.

                                                          -

                                                          Parameters

                                                          • mode: number

                                                            The mode value (1-4).

                                                            -

                                                          Returns Promise<boolean>

                                                            -
                                                          • Resolves with true if the operation was successful.
                                                          • -
                                                          -
                                                        • Sets the speed of the air purifier.

                                                          -

                                                          Parameters

                                                          • speed: number

                                                            The speed value (0-100).

                                                            -

                                                          Returns Promise<boolean>

                                                            -
                                                          • Resolves with true if the operation was successful.
                                                          • -
                                                          -
                                                        • Turns the air purifier off.

                                                          -

                                                          Returns Promise<boolean>

                                                            -
                                                          • Resolves with true if the air purifier is turned off.
                                                          • -
                                                          -
                                                        • Turns the air purifier on.

                                                          -

                                                          Returns Promise<boolean>

                                                            -
                                                          • Resolves with true if the air purifier is turned on.
                                                          • -
                                                          -
                                                        • Parses service data for air purifier devices.

                                                          -

                                                          Parameters

                                                          • serviceData: null | Buffer<ArrayBufferLike>

                                                            The service data buffer.

                                                            -
                                                          • manufacturerData: null | Buffer<ArrayBufferLike>

                                                            The manufacturer data buffer.

                                                            -
                                                          • OptionalemitLog: (level: string, message: string) => void

                                                            The function to emit log messages.

                                                            -

                                                          Returns null | airPurifierServiceData

                                                            -
                                                          • The parsed service data or null.
                                                          • -
                                                          -
                                                        +unregisterFallbackHandler +update +updateInfo +verifyEncryptionKey +

                                                        Constructors

                                                        • Parameters

                                                          • info: DeviceInfo
                                                          • options: {
                                                                apiClient?: OpenAPIClient;
                                                                bleConnection?: BLEConnection;
                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                enableCircuitBreaker?: boolean;
                                                                enableConnectionIntelligence?: boolean;
                                                                enableFallback?: boolean;
                                                                enableRetry?: boolean;
                                                                logLevel?: number;
                                                                preferredConnection?: ConnectionType;
                                                                retryConfig?: RetryConfig;
                                                            } = {}

                                                          Returns WoAirPurifier

                                                        Accessors

                                                        • get deviceType(): string

                                                          Get device type (property accessor for convenience)

                                                          +

                                                          Returns string

                                                        • get id(): string | undefined

                                                          Get device ID (property accessor for convenience)

                                                          +

                                                          Returns string | undefined

                                                        • get mac(): string | undefined

                                                          Get MAC address (property accessor for convenience)

                                                          +

                                                          Returns string | undefined

                                                        • get name(): string

                                                          Get device name (property accessor for convenience)

                                                          +

                                                          Returns string

                                                        Methods

                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                          +

                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                          +

                                                          Returns a CommandResult object with device info fields.

                                                          +

                                                          Returns Promise<CommandResult>

                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                          +

                                                          Parameters

                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                          Returns boolean

                                                        • Register a custom fallback handler

                                                          +

                                                          Parameters

                                                          • handler: FallbackHandler
                                                          • Optionaloptions: FallbackHandlerOptions

                                                          Returns string

                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                          +

                                                          Parameters

                                                          • commands: (() => Promise<boolean>)[]

                                                          Returns Promise<boolean>

                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                          +

                                                          Parameters

                                                          • commands: (() => Promise<boolean>)[]

                                                          Returns Promise<boolean>

                                                        • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                          +

                                                          Parameters

                                                          • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                          Returns Promise<boolean>

                                                        • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                          +

                                                          Returns Promise<boolean>

                                                        diff --git a/docs/classes/WoAirPurifierPM25.html b/docs/classes/WoAirPurifierPM25.html new file mode 100644 index 00000000..cf1b8ea4 --- /dev/null +++ b/docs/classes/WoAirPurifierPM25.html @@ -0,0 +1,117 @@ +WoAirPurifierPM25 | node-switchbot
                                                        node-switchbot
                                                          Preparing search index...

                                                          Class WoAirPurifierPM25

                                                          Base class for all SwitchBot devices

                                                          + +

                                                          This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                          +
                                                            +
                                                          • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                          • +
                                                          • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                          • +
                                                          • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                          • +
                                                          • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                          • +
                                                          + +
                                                            +
                                                          • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                          • +
                                                          • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                          • +
                                                          • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                          • +
                                                          + +
                                                          async getStatus(): Promise<DeviceStatus> {
                                                          return this.getStatusWithFallback(
                                                          bleData => ({ ... }), // normalize BLE data
                                                          apiData => ({ ... }), // normalize API data
                                                          )
                                                          }

                                                          async turnOn(): Promise<boolean> {
                                                          const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                          return result.success
                                                          } +
                                                          + + +
                                                            +
                                                          • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                          • +
                                                          • enableFallback: boolean (default: true)
                                                          • +
                                                          • enableConnectionIntelligence: boolean (default: true)
                                                          • +
                                                          • enableCircuitBreaker: boolean (default: true)
                                                          • +
                                                          • enableRetry: boolean (default: true)
                                                          • +
                                                          + +
                                                            +
                                                          • getStatusWithFallback()
                                                          • +
                                                          • sendCommand()
                                                          • +
                                                          • hasBLE(), hasAPI()
                                                          • +
                                                          • setPreferredConnection(), setFallbackEnabled()
                                                          • +
                                                          +

                                                          This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                          +

                                                          Hierarchy (View Summary)

                                                          Index

                                                          Constructors

                                                          • Parameters

                                                            • info: DeviceInfo
                                                            • options: {
                                                                  apiClient?: OpenAPIClient;
                                                                  bleConnection?: BLEConnection;
                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                  enableCircuitBreaker?: boolean;
                                                                  enableConnectionIntelligence?: boolean;
                                                                  enableFallback?: boolean;
                                                                  enableRetry?: boolean;
                                                                  logLevel?: number;
                                                                  preferredConnection?: ConnectionType;
                                                                  retryConfig?: RetryConfig;
                                                              } = {}

                                                            Returns WoAirPurifierPM25

                                                          Accessors

                                                          • get deviceType(): string

                                                            Get device type (property accessor for convenience)

                                                            +

                                                            Returns string

                                                          • get id(): string | undefined

                                                            Get device ID (property accessor for convenience)

                                                            +

                                                            Returns string | undefined

                                                          • get mac(): string | undefined

                                                            Get MAC address (property accessor for convenience)

                                                            +

                                                            Returns string | undefined

                                                          • get name(): string

                                                            Get device name (property accessor for convenience)

                                                            +

                                                            Returns string

                                                          Methods

                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                            +

                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                            +

                                                            Returns a CommandResult object with device info fields.

                                                            +

                                                            Returns Promise<CommandResult>

                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                            +

                                                            Parameters

                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                            Returns boolean

                                                          • Register a custom fallback handler

                                                            +

                                                            Parameters

                                                            • handler: FallbackHandler
                                                            • Optionaloptions: FallbackHandlerOptions

                                                            Returns string

                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                            +

                                                            Parameters

                                                            • commands: (() => Promise<boolean>)[]

                                                            Returns Promise<boolean>

                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                            +

                                                            Parameters

                                                            • commands: (() => Promise<boolean>)[]

                                                            Returns Promise<boolean>

                                                          • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                            +

                                                            Parameters

                                                            • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                            Returns Promise<boolean>

                                                          diff --git a/docs/classes/WoAirPurifierTable.html b/docs/classes/WoAirPurifierTable.html index 15196e39..f7f29db4 100644 --- a/docs/classes/WoAirPurifierTable.html +++ b/docs/classes/WoAirPurifierTable.html @@ -1,83 +1,89 @@ -WoAirPurifierTable | node-switchbot
                                                          node-switchbot
                                                            Preparing search index...

                                                            Class WoAirPurifierTable

                                                            Class representing a SwitchBot Air Purifier Table device.

                                                            -

                                                            Hierarchy (View Summary)

                                                            Index

                                                            Constructors

                                                            Accessors

                                                            address -connectionState -friendlyName +WoAirPurifierTable | node-switchbot
                                                            node-switchbot
                                                              Preparing search index...

                                                              Class WoAirPurifierTable

                                                              Air Purifier Table Device +Uses same logic as standard Air Purifier

                                                              +

                                                              Hierarchy (View Summary)

                                                              Index

                                                              Constructors

                                                              Accessors

                                                              • get address(): string

                                                                Returns string

                                                              • get connectionState(): string

                                                                Returns string

                                                              • get id(): string

                                                                Returns string

                                                              • get onConnectHandler(): () => Promise<void>

                                                                Returns () => Promise<void>

                                                              • set onConnectHandler(func: () => Promise<void>): void

                                                                Parameters

                                                                • func: () => Promise<void>

                                                                Returns void

                                                              • get onDisconnectHandler(): () => Promise<void>

                                                                Returns () => Promise<void>

                                                              • set onDisconnectHandler(func: () => Promise<void>): void

                                                                Parameters

                                                                • func: () => Promise<void>

                                                                Returns void

                                                              Methods

                                                              • Sends a command to the device and awaits a response.

                                                                -

                                                                Parameters

                                                                • reqBuf: Buffer

                                                                  The command buffer.

                                                                  -

                                                                Returns Promise<Buffer<ArrayBufferLike>>

                                                                A Promise that resolves with the response buffer.

                                                                -
                                                              • Internal method to handle the connection process.

                                                                -

                                                                Returns Promise<void>

                                                                A Promise that resolves when the connection is complete.

                                                                -
                                                              • Logs a message with the specified log level.

                                                                -

                                                                Parameters

                                                                • level: string

                                                                  The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                  -
                                                                • message: string

                                                                  The log message to be emitted.

                                                                  -

                                                                Returns Promise<void>

                                                              • Operates the air purifier table with the given byte array.

                                                                -

                                                                Parameters

                                                                • bytes: number[]

                                                                  The byte array to send.

                                                                  -

                                                                Returns Promise<boolean>

                                                                  -
                                                                • Resolves with true if the operation was successful.
                                                                • -
                                                                -
                                                              • Sets the device name.

                                                                -

                                                                Parameters

                                                                • name: string

                                                                  The new device name.

                                                                  -

                                                                Returns Promise<void>

                                                                A Promise that resolves when the name is set.

                                                                -
                                                              • Sets the mode of the air purifier table.

                                                                -

                                                                Parameters

                                                                • mode: number

                                                                  The mode value (1-4).

                                                                  -

                                                                Returns Promise<boolean>

                                                                  -
                                                                • Resolves with true if the operation was successful.
                                                                • -
                                                                -
                                                              • Sets the speed of the air purifier table.

                                                                -

                                                                Parameters

                                                                • speed: number

                                                                  The speed value (0-100).

                                                                  -

                                                                Returns Promise<boolean>

                                                                  -
                                                                • Resolves with true if the operation was successful.
                                                                • -
                                                                -
                                                              • Turns the air purifier table off.

                                                                -

                                                                Returns Promise<boolean>

                                                                  -
                                                                • Resolves with true if the air purifier table is turned off.
                                                                • -
                                                                -
                                                              • Turns the air purifier table on.

                                                                -

                                                                Returns Promise<boolean>

                                                                  -
                                                                • Resolves with true if the air purifier table is turned on.
                                                                • -
                                                                -
                                                              • Parses service data for air purifier table devices.

                                                                -

                                                                Parameters

                                                                • serviceData: null | Buffer<ArrayBufferLike>

                                                                  The service data buffer.

                                                                  -
                                                                • manufacturerData: null | Buffer<ArrayBufferLike>

                                                                  The manufacturer data buffer.

                                                                  -
                                                                • OptionalemitLog: (level: string, message: string) => void

                                                                  The function to emit log messages.

                                                                  -

                                                                Returns null | airPurifierTableServiceData

                                                                  -
                                                                • The parsed service data or null.
                                                                • -
                                                                -
                                                              +mac +name +

                                                              Methods

                                                              Constructors

                                                              • Parameters

                                                                • info: DeviceInfo
                                                                • options: {
                                                                      apiClient?: OpenAPIClient;
                                                                      bleConnection?: BLEConnection;
                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                      enableCircuitBreaker?: boolean;
                                                                      enableConnectionIntelligence?: boolean;
                                                                      enableFallback?: boolean;
                                                                      enableRetry?: boolean;
                                                                      logLevel?: number;
                                                                      preferredConnection?: ConnectionType;
                                                                      retryConfig?: RetryConfig;
                                                                  } = {}

                                                                Returns WoAirPurifierTable

                                                              Accessors

                                                              • get deviceType(): string

                                                                Get device type (property accessor for convenience)

                                                                +

                                                                Returns string

                                                              • get id(): string | undefined

                                                                Get device ID (property accessor for convenience)

                                                                +

                                                                Returns string | undefined

                                                              • get mac(): string | undefined

                                                                Get MAC address (property accessor for convenience)

                                                                +

                                                                Returns string | undefined

                                                              • get name(): string

                                                                Get device name (property accessor for convenience)

                                                                +

                                                                Returns string

                                                              Methods

                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                +

                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                +

                                                                Returns a CommandResult object with device info fields.

                                                                +

                                                                Returns Promise<CommandResult>

                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                +

                                                                Parameters

                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                Returns boolean

                                                              • Register a custom fallback handler

                                                                +

                                                                Parameters

                                                                • handler: FallbackHandler
                                                                • Optionaloptions: FallbackHandlerOptions

                                                                Returns string

                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                +

                                                                Parameters

                                                                • commands: (() => Promise<boolean>)[]

                                                                Returns Promise<boolean>

                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                +

                                                                Parameters

                                                                • commands: (() => Promise<boolean>)[]

                                                                Returns Promise<boolean>

                                                              • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                                +

                                                                Parameters

                                                                • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                                Returns Promise<boolean>

                                                              diff --git a/docs/classes/WoArtFrame.html b/docs/classes/WoArtFrame.html new file mode 100644 index 00000000..04599561 --- /dev/null +++ b/docs/classes/WoArtFrame.html @@ -0,0 +1,103 @@ +WoArtFrame | node-switchbot
                                                              node-switchbot
                                                                Preparing search index...

                                                                Class WoArtFrame

                                                                Art Frame Device +Uses same logic as Color Bulb

                                                                +

                                                                Hierarchy (View Summary)

                                                                Index

                                                                Constructors

                                                                • Parameters

                                                                  • info: DeviceInfo
                                                                  • options: {
                                                                        apiClient?: OpenAPIClient;
                                                                        bleConnection?: BLEConnection;
                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                        enableCircuitBreaker?: boolean;
                                                                        enableConnectionIntelligence?: boolean;
                                                                        enableFallback?: boolean;
                                                                        enableRetry?: boolean;
                                                                        logLevel?: number;
                                                                        preferredConnection?: ConnectionType;
                                                                        retryConfig?: RetryConfig;
                                                                    } = {}

                                                                  Returns WoArtFrame

                                                                Properties

                                                                EFFECTS: Record<string, number> = ...

                                                                Preset effect name to effect ID mapping

                                                                +

                                                                Accessors

                                                                • get deviceType(): string

                                                                  Get device type (property accessor for convenience)

                                                                  +

                                                                  Returns string

                                                                • get id(): string | undefined

                                                                  Get device ID (property accessor for convenience)

                                                                  +

                                                                  Returns string | undefined

                                                                • get mac(): string | undefined

                                                                  Get MAC address (property accessor for convenience)

                                                                  +

                                                                  Returns string | undefined

                                                                • get name(): string

                                                                  Get device name (property accessor for convenience)

                                                                  +

                                                                  Returns string

                                                                Methods

                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                  +

                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                  +

                                                                  Returns a CommandResult object with device info fields.

                                                                  +

                                                                  Returns Promise<CommandResult>

                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                  +

                                                                  Parameters

                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                  Returns boolean

                                                                • Register a custom fallback handler

                                                                  +

                                                                  Parameters

                                                                  • handler: FallbackHandler
                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                  Returns string

                                                                • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                  +

                                                                  Parameters

                                                                  • commands: (() => Promise<boolean>)[]

                                                                  Returns Promise<boolean>

                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                  +

                                                                  Parameters

                                                                  • commands: (() => Promise<boolean>)[]

                                                                  Returns Promise<boolean>

                                                                • Set RGB color

                                                                  +

                                                                  Parameters

                                                                  • red: number
                                                                  • green: number
                                                                  • blue: number

                                                                  Returns Promise<boolean>

                                                                • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                  +

                                                                  Parameters

                                                                  • minTemp: number
                                                                  • maxTemp: number
                                                                  • temp: number

                                                                  Returns Promise<boolean>

                                                                • Set preset light effect

                                                                  +

                                                                  Parameters

                                                                  • effectName: string
                                                                  • speed: number = 100

                                                                  Returns Promise<boolean>

                                                                • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                  +

                                                                  Parameters

                                                                  • mode: string | number

                                                                    Mode value (number or string, per-device enum recommended)

                                                                    +

                                                                    Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                    +

                                                                    Returns a CommandResult object indicating success and mode info.

                                                                    +

                                                                  Returns Promise<CommandResult>

                                                                • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                  +

                                                                  Returns Promise<boolean>

                                                                diff --git a/docs/classes/WoBlindTilt.html b/docs/classes/WoBlindTilt.html index c661f9bc..9b7bd33c 100644 --- a/docs/classes/WoBlindTilt.html +++ b/docs/classes/WoBlindTilt.html @@ -1,78 +1,89 @@ -WoBlindTilt | node-switchbot
                                                                node-switchbot
                                                                  Preparing search index...

                                                                  Class WoBlindTilt

                                                                  Class representing a WoBlindTilt device.

                                                                  -

                                                                  Hierarchy (View Summary)

                                                                  Index

                                                                  Constructors

                                                                  Accessors

                                                                  address -connectionState -friendlyName +WoBlindTilt | node-switchbot
                                                                  node-switchbot
                                                                    Preparing search index...

                                                                    Class WoBlindTilt

                                                                    Blind Tilt Device

                                                                    +

                                                                    Hierarchy (View Summary)

                                                                    Implements

                                                                    Index

                                                                    Constructors

                                                                    Accessors

                                                                    • get address(): string

                                                                      Returns string

                                                                    • get connectionState(): string

                                                                      Returns string

                                                                    • get id(): string

                                                                      Returns string

                                                                    • get onConnectHandler(): () => Promise<void>

                                                                      Returns () => Promise<void>

                                                                    • set onConnectHandler(func: () => Promise<void>): void

                                                                      Parameters

                                                                      • func: () => Promise<void>

                                                                      Returns void

                                                                    • get onDisconnectHandler(): () => Promise<void>

                                                                      Returns () => Promise<void>

                                                                    • set onDisconnectHandler(func: () => Promise<void>): void

                                                                      Parameters

                                                                      • func: () => Promise<void>

                                                                      Returns void

                                                                    Methods

                                                                    • Closes the blind tilt to the nearest endpoint.

                                                                      -

                                                                      Returns Promise<void>

                                                                    • Closes the blind tilt down to the nearest endpoint.

                                                                      -

                                                                      Returns Promise<void>

                                                                    • Closes the blind tilt up to the nearest endpoint.

                                                                      -

                                                                      Returns Promise<void>

                                                                    • Sends a command to the device and awaits a response.

                                                                      -

                                                                      Parameters

                                                                      • reqBuf: Buffer

                                                                        The command buffer.

                                                                        -

                                                                      Returns Promise<Buffer<ArrayBufferLike>>

                                                                      A Promise that resolves with the response buffer.

                                                                      -
                                                                    • Retrieves the basic information of the blind tilt.

                                                                      -

                                                                      Returns Promise<null | object>

                                                                        -
                                                                      • A promise that resolves to an object containing the basic information of the blind tilt.
                                                                      • -
                                                                      -
                                                                    • Retrieves the current position of the blind tilt.

                                                                      -

                                                                      Returns Promise<number>

                                                                        -
                                                                      • The current position of the blind tilt (0-100).
                                                                      • -
                                                                      -
                                                                    • Internal method to handle the connection process.

                                                                      -

                                                                      Returns Promise<void>

                                                                      A Promise that resolves when the connection is complete.

                                                                      -
                                                                    • Logs a message with the specified log level.

                                                                      -

                                                                      Parameters

                                                                      • level: string

                                                                        The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                        -
                                                                      • message: string

                                                                        The log message to be emitted.

                                                                        -

                                                                      Returns Promise<void>

                                                                    • Opens the blind tilt to the fully open position.

                                                                      -

                                                                      Returns Promise<void>

                                                                    • Pauses the blind tilt operation.

                                                                      -

                                                                      Returns Promise<void>

                                                                    • Runs the blind tilt to the specified position.

                                                                      -

                                                                      Parameters

                                                                      • percent: number

                                                                        The target position percentage (0-100).

                                                                        -
                                                                      • mode: number

                                                                        The running mode (0 or 1).

                                                                        -

                                                                      Returns Promise<void>

                                                                    • Sets the device name.

                                                                      -

                                                                      Parameters

                                                                      • name: string

                                                                        The new device name.

                                                                        -

                                                                      Returns Promise<void>

                                                                      A Promise that resolves when the name is set.

                                                                      -
                                                                    • Parses the service data and manufacturer data for the WoBlindTilt device.

                                                                      -

                                                                      Parameters

                                                                      • serviceData: Buffer

                                                                        The service data buffer.

                                                                        -
                                                                      • manufacturerData: Buffer

                                                                        The manufacturer data buffer.

                                                                        -
                                                                      • emitLog: (level: string, message: string) => void

                                                                        The function to emit log messages.

                                                                        -
                                                                      • Optionalreverse: boolean = false

                                                                        Whether to reverse the tilt percentage.

                                                                        -

                                                                      Returns Promise<null | blindTiltServiceData>

                                                                        -
                                                                      • The parsed data object or null if the data is invalid.
                                                                      • -
                                                                      -
                                                                    +pollIfNeeded +pollNeeded +registerFallbackHandler +sendCommandSequence +sendMultipleCommands +setCircuitBreakerEnabled +setConnectionIntelligenceEnabled +setFallbackEnabled +setMode +setPosition +setPreferredConnection +setRetryEnabled +unregisterFallbackHandler +updateInfo +

                                                                    Constructors

                                                                    • Parameters

                                                                      • info: DeviceInfo
                                                                      • options: {
                                                                            apiClient?: OpenAPIClient;
                                                                            bleConnection?: BLEConnection;
                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                            enableCircuitBreaker?: boolean;
                                                                            enableConnectionIntelligence?: boolean;
                                                                            enableFallback?: boolean;
                                                                            enableRetry?: boolean;
                                                                            logLevel?: number;
                                                                            preferredConnection?: ConnectionType;
                                                                            retryConfig?: RetryConfig;
                                                                        } = {}

                                                                      Returns WoBlindTilt

                                                                    Accessors

                                                                    • get deviceType(): string

                                                                      Get device type (property accessor for convenience)

                                                                      +

                                                                      Returns string

                                                                    • get id(): string | undefined

                                                                      Get device ID (property accessor for convenience)

                                                                      +

                                                                      Returns string | undefined

                                                                    • get mac(): string | undefined

                                                                      Get MAC address (property accessor for convenience)

                                                                      +

                                                                      Returns string | undefined

                                                                    • get name(): string

                                                                      Get device name (property accessor for convenience)

                                                                      +

                                                                      Returns string

                                                                    Methods

                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                      +

                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                      +

                                                                      Returns a CommandResult object with device info fields.

                                                                      +

                                                                      Returns Promise<CommandResult>

                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                      +

                                                                      Parameters

                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                      Returns boolean

                                                                    • Register a custom fallback handler

                                                                      +

                                                                      Parameters

                                                                      • handler: FallbackHandler
                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                      Returns string

                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                      +

                                                                      Parameters

                                                                      • commands: (() => Promise<boolean>)[]

                                                                      Returns Promise<boolean>

                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                      +

                                                                      Parameters

                                                                      • commands: (() => Promise<boolean>)[]

                                                                      Returns Promise<boolean>

                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                      +

                                                                      Parameters

                                                                      • mode: string | number

                                                                        Mode value (number or string, per-device enum recommended)

                                                                        +

                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                        +

                                                                        Returns a CommandResult object indicating success and mode info.

                                                                        +

                                                                      Returns Promise<CommandResult>

                                                                    diff --git a/docs/classes/WoBulb.html b/docs/classes/WoBulb.html index 2bc3d780..527c7392 100644 --- a/docs/classes/WoBulb.html +++ b/docs/classes/WoBulb.html @@ -1,89 +1,102 @@ -WoBulb | node-switchbot
                                                                    node-switchbot
                                                                      Preparing search index...

                                                                      Class WoBulb

                                                                      Class representing a WoBulb device.

                                                                      -

                                                                      Hierarchy (View Summary)

                                                                      Index

                                                                      Constructors

                                                                      Accessors

                                                                      address -connectionState -friendlyName +WoBulb | node-switchbot
                                                                      node-switchbot
                                                                        Preparing search index...

                                                                        Class WoBulb

                                                                        Color Bulb Device

                                                                        +

                                                                        Hierarchy (View Summary)

                                                                        Implements

                                                                        Index

                                                                        Constructors

                                                                        Accessors

                                                                        • get address(): string

                                                                          Returns string

                                                                        • get connectionState(): string

                                                                          Returns string

                                                                        • get id(): string

                                                                          Returns string

                                                                        • get onConnectHandler(): () => Promise<void>

                                                                          Returns () => Promise<void>

                                                                        • set onConnectHandler(func: () => Promise<void>): void

                                                                          Parameters

                                                                          • func: () => Promise<void>

                                                                          Returns void

                                                                        • get onDisconnectHandler(): () => Promise<void>

                                                                          Returns () => Promise<void>

                                                                        • set onDisconnectHandler(func: () => Promise<void>): void

                                                                          Parameters

                                                                          • func: () => Promise<void>

                                                                          Returns void

                                                                        Methods

                                                                        • Sends a command to the device and awaits a response.

                                                                          -

                                                                          Parameters

                                                                          • reqBuf: Buffer

                                                                            The command buffer.

                                                                            -

                                                                          Returns Promise<Buffer<ArrayBufferLike>>

                                                                          A Promise that resolves with the response buffer.

                                                                          -
                                                                        • Internal method to handle the connection process.

                                                                          -

                                                                          Returns Promise<void>

                                                                          A Promise that resolves when the connection is complete.

                                                                          -
                                                                        • Logs a message with the specified log level.

                                                                          -

                                                                          Parameters

                                                                          • level: string

                                                                            The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                            -
                                                                          • message: string

                                                                            The log message to be emitted.

                                                                            -

                                                                          Returns Promise<void>

                                                                        • Reads the state of the bulb.

                                                                          -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the bulb is ON (true) or OFF (false).
                                                                          • -
                                                                          -
                                                                        • Sets the brightness of the bulb.

                                                                          -

                                                                          Parameters

                                                                          • brightness: number

                                                                            The brightness percentage (0-100).

                                                                            -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the operation was successful.
                                                                          • -
                                                                          -
                                                                        • Sets the color temperature of the bulb.

                                                                          -

                                                                          Parameters

                                                                          • color_temperature: number

                                                                            The color temperature percentage (0-100).

                                                                            -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the operation was successful.
                                                                          • -
                                                                          -
                                                                        • Sets the device name.

                                                                          -

                                                                          Parameters

                                                                          • name: string

                                                                            The new device name.

                                                                            -

                                                                          Returns Promise<void>

                                                                          A Promise that resolves when the name is set.

                                                                          -
                                                                        • Sets the RGB color of the bulb.

                                                                          -

                                                                          Parameters

                                                                          • brightness: number

                                                                            The brightness percentage (0-100).

                                                                            -
                                                                          • red: number

                                                                            The red color value (0-255).

                                                                            -
                                                                          • green: number

                                                                            The green color value (0-255).

                                                                            -
                                                                          • blue: number

                                                                            The blue color value (0-255).

                                                                            -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the operation was successful.
                                                                          • -
                                                                          -
                                                                        • Turns off the bulb.

                                                                          -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the bulb is OFF (false).
                                                                          • -
                                                                          -
                                                                        • Turns on the bulb.

                                                                          -

                                                                          Returns Promise<boolean>

                                                                            -
                                                                          • Resolves with a boolean indicating whether the bulb is ON (true).
                                                                          • -
                                                                          -
                                                                        • Parses the service data for WoBulb.

                                                                          -

                                                                          Parameters

                                                                          • serviceData: Buffer

                                                                            The service data buffer.

                                                                            -
                                                                          • manufacturerData: Buffer

                                                                            The manufacturer data buffer.

                                                                            -
                                                                          • emitLog: (level: string, message: string) => void

                                                                            The function to emit log messages.

                                                                            -

                                                                          Returns Promise<null | colorBulbServiceData>

                                                                            -
                                                                          • Parsed service data or null if invalid.
                                                                          • -
                                                                          -
                                                                        +unregisterFallbackHandler +updateInfo +verifyEncryptionKey +

                                                                        Constructors

                                                                        • Parameters

                                                                          • info: DeviceInfo
                                                                          • options: {
                                                                                apiClient?: OpenAPIClient;
                                                                                bleConnection?: BLEConnection;
                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                enableCircuitBreaker?: boolean;
                                                                                enableConnectionIntelligence?: boolean;
                                                                                enableFallback?: boolean;
                                                                                enableRetry?: boolean;
                                                                                logLevel?: number;
                                                                                preferredConnection?: ConnectionType;
                                                                                retryConfig?: RetryConfig;
                                                                            } = {}

                                                                          Returns WoBulb

                                                                        Properties

                                                                        EFFECTS: Record<string, number> = ...

                                                                        Preset effect name to effect ID mapping

                                                                        +

                                                                        Accessors

                                                                        • get deviceType(): string

                                                                          Get device type (property accessor for convenience)

                                                                          +

                                                                          Returns string

                                                                        • get id(): string | undefined

                                                                          Get device ID (property accessor for convenience)

                                                                          +

                                                                          Returns string | undefined

                                                                        • get mac(): string | undefined

                                                                          Get MAC address (property accessor for convenience)

                                                                          +

                                                                          Returns string | undefined

                                                                        • get name(): string

                                                                          Get device name (property accessor for convenience)

                                                                          +

                                                                          Returns string

                                                                        Methods

                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                          +

                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                          +

                                                                          Returns a CommandResult object with device info fields.

                                                                          +

                                                                          Returns Promise<CommandResult>

                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                          +

                                                                          Parameters

                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                          Returns boolean

                                                                        • Register a custom fallback handler

                                                                          +

                                                                          Parameters

                                                                          • handler: FallbackHandler
                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                          Returns string

                                                                        • Set RGB color

                                                                          +

                                                                          Parameters

                                                                          • red: number
                                                                          • green: number
                                                                          • blue: number

                                                                          Returns Promise<boolean>

                                                                        • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                          +

                                                                          Parameters

                                                                          • minTemp: number
                                                                          • maxTemp: number
                                                                          • temp: number

                                                                          Returns Promise<boolean>

                                                                        • Set preset light effect

                                                                          +

                                                                          Parameters

                                                                          • effectName: string
                                                                          • speed: number = 100

                                                                          Returns Promise<boolean>

                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                          +

                                                                          Parameters

                                                                          • mode: string | number

                                                                            Mode value (number or string, per-device enum recommended)

                                                                            +

                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                            +

                                                                            Returns a CommandResult object indicating success and mode info.

                                                                            +

                                                                          Returns Promise<CommandResult>

                                                                        • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                          +

                                                                          Returns Promise<boolean>

                                                                        diff --git a/docs/classes/WoCandleWarmerLamp.html b/docs/classes/WoCandleWarmerLamp.html new file mode 100644 index 00000000..5726b870 --- /dev/null +++ b/docs/classes/WoCandleWarmerLamp.html @@ -0,0 +1,122 @@ +WoCandleWarmerLamp | node-switchbot
                                                                        node-switchbot
                                                                          Preparing search index...

                                                                          Class WoCandleWarmerLamp

                                                                          Base class for all SwitchBot devices

                                                                          + +

                                                                          This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                                          +
                                                                            +
                                                                          • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                                          • +
                                                                          • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                                          • +
                                                                          • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                                          • +
                                                                          • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                                          • +
                                                                          + +
                                                                            +
                                                                          • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                                          • +
                                                                          • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                                          • +
                                                                          • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                                          • +
                                                                          + +
                                                                          async getStatus(): Promise<DeviceStatus> {
                                                                          return this.getStatusWithFallback(
                                                                          bleData => ({ ... }), // normalize BLE data
                                                                          apiData => ({ ... }), // normalize API data
                                                                          )
                                                                          }

                                                                          async turnOn(): Promise<boolean> {
                                                                          const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                                          return result.success
                                                                          } +
                                                                          + + +
                                                                            +
                                                                          • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                                          • +
                                                                          • enableFallback: boolean (default: true)
                                                                          • +
                                                                          • enableConnectionIntelligence: boolean (default: true)
                                                                          • +
                                                                          • enableCircuitBreaker: boolean (default: true)
                                                                          • +
                                                                          • enableRetry: boolean (default: true)
                                                                          • +
                                                                          + +
                                                                            +
                                                                          • getStatusWithFallback()
                                                                          • +
                                                                          • sendCommand()
                                                                          • +
                                                                          • hasBLE(), hasAPI()
                                                                          • +
                                                                          • setPreferredConnection(), setFallbackEnabled()
                                                                          • +
                                                                          +

                                                                          This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                                          +

                                                                          Hierarchy (View Summary)

                                                                          Index

                                                                          Constructors

                                                                          • Parameters

                                                                            • info: DeviceInfo
                                                                            • options: {
                                                                                  apiClient?: OpenAPIClient;
                                                                                  bleConnection?: BLEConnection;
                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                  enableCircuitBreaker?: boolean;
                                                                                  enableConnectionIntelligence?: boolean;
                                                                                  enableFallback?: boolean;
                                                                                  enableRetry?: boolean;
                                                                                  logLevel?: number;
                                                                                  preferredConnection?: ConnectionType;
                                                                                  retryConfig?: RetryConfig;
                                                                              } = {}

                                                                            Returns WoCandleWarmerLamp

                                                                          Accessors

                                                                          • get deviceType(): string

                                                                            Get device type (property accessor for convenience)

                                                                            +

                                                                            Returns string

                                                                          • get id(): string | undefined

                                                                            Get device ID (property accessor for convenience)

                                                                            +

                                                                            Returns string | undefined

                                                                          • get mac(): string | undefined

                                                                            Get MAC address (property accessor for convenience)

                                                                            +

                                                                            Returns string | undefined

                                                                          • get name(): string

                                                                            Get device name (property accessor for convenience)

                                                                            +

                                                                            Returns string

                                                                          Methods

                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                            +

                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                            +

                                                                            Returns a CommandResult object with device info fields.

                                                                            +

                                                                            Returns Promise<CommandResult>

                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                            +

                                                                            Parameters

                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                            Returns boolean

                                                                          • Register a custom fallback handler

                                                                            +

                                                                            Parameters

                                                                            • handler: FallbackHandler
                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                            Returns string

                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                            +

                                                                            Parameters

                                                                            • commands: (() => Promise<boolean>)[]

                                                                            Returns Promise<boolean>

                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                            +

                                                                            Parameters

                                                                            • commands: (() => Promise<boolean>)[]

                                                                            Returns Promise<boolean>

                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                            +

                                                                            Parameters

                                                                            • mode: string | number

                                                                              Mode value (number or string, per-device enum recommended)

                                                                              +

                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                              +

                                                                              Returns a CommandResult object indicating success and mode info.

                                                                              +

                                                                            Returns Promise<CommandResult>

                                                                          diff --git a/docs/classes/WoCeilingLight.html b/docs/classes/WoCeilingLight.html index 72a9c395..b3ff8839 100644 --- a/docs/classes/WoCeilingLight.html +++ b/docs/classes/WoCeilingLight.html @@ -1,107 +1,103 @@ -WoCeilingLight | node-switchbot
                                                                          node-switchbot
                                                                            Preparing search index...

                                                                            Class WoCeilingLight

                                                                            Class representing a WoCeilingLight device.

                                                                            -

                                                                            Hierarchy (View Summary)

                                                                            Index

                                                                            Constructors

                                                                            Accessors

                                                                            address -connectionState -friendlyName +WoCeilingLight | node-switchbot
                                                                            node-switchbot
                                                                              Preparing search index...

                                                                              Class WoCeilingLight

                                                                              Ceiling Light Device +Uses same logic as Color Bulb

                                                                              +

                                                                              Hierarchy (View Summary)

                                                                              Index

                                                                              Constructors

                                                                              Accessors

                                                                              • get address(): string

                                                                                Returns string

                                                                              • get connectionState(): string

                                                                                Returns string

                                                                              • get id(): string

                                                                                Returns string

                                                                              • get onConnectHandler(): () => Promise<void>

                                                                                Returns () => Promise<void>

                                                                              • set onConnectHandler(func: () => Promise<void>): void

                                                                                Parameters

                                                                                • func: () => Promise<void>

                                                                                Returns void

                                                                              • get onDisconnectHandler(): () => Promise<void>

                                                                                Returns () => Promise<void>

                                                                              • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                Parameters

                                                                                • func: () => Promise<void>

                                                                                Returns void

                                                                              Methods

                                                                              • Sends a command to the device and awaits a response.

                                                                                -

                                                                                Parameters

                                                                                • reqBuf: Buffer

                                                                                  The command buffer.

                                                                                  -

                                                                                Returns Promise<Buffer<ArrayBufferLike>>

                                                                                A Promise that resolves with the response buffer.

                                                                                -
                                                                              • Internal method to handle the connection process.

                                                                                -

                                                                                Returns Promise<void>

                                                                                A Promise that resolves when the connection is complete.

                                                                                -
                                                                              • Logs a message with the specified log level.

                                                                                -

                                                                                Parameters

                                                                                • level: string

                                                                                  The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                  -
                                                                                • message: string

                                                                                  The log message to be emitted.

                                                                                  -

                                                                                Returns Promise<void>

                                                                              • Sends a command to the ceiling light.

                                                                                -

                                                                                Parameters

                                                                                • bytes: number[]

                                                                                  The command bytes.

                                                                                  -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the operation was successful.
                                                                                • -
                                                                                -
                                                                              • Reads the state of the ceiling light.

                                                                                -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the light is ON (true) or OFF (false).
                                                                                • -
                                                                                -
                                                                              • Sets the brightness of the ceiling light.

                                                                                -

                                                                                Parameters

                                                                                • brightness: number

                                                                                  The brightness percentage (0-100).

                                                                                  -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the operation was successful.
                                                                                • -
                                                                                -
                                                                              • Sets the color temperature of the ceiling light.

                                                                                -

                                                                                Parameters

                                                                                • color_temperature: number

                                                                                  The color temperature percentage (0-100).

                                                                                  -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the operation was successful.
                                                                                • -
                                                                                -
                                                                              • Sets the device name.

                                                                                -

                                                                                Parameters

                                                                                • name: string

                                                                                  The new device name.

                                                                                  -

                                                                                Returns Promise<void>

                                                                                A Promise that resolves when the name is set.

                                                                                -
                                                                              • Sets the RGB color of the ceiling light.

                                                                                -

                                                                                Parameters

                                                                                • brightness: number

                                                                                  The brightness percentage (0-100).

                                                                                  -
                                                                                • red: number

                                                                                  The red color value (0-255).

                                                                                  -
                                                                                • green: number

                                                                                  The green color value (0-255).

                                                                                  -
                                                                                • blue: number

                                                                                  The blue color value (0-255).

                                                                                  -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the operation was successful.
                                                                                • -
                                                                                -
                                                                              • Sets the state of the ceiling light.

                                                                                -

                                                                                Parameters

                                                                                • reqByteArray: number[]

                                                                                  The request byte array.

                                                                                  -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the operation was successful.
                                                                                • -
                                                                                -
                                                                              • Turns off the ceiling light.

                                                                                -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the light is OFF (false).
                                                                                • -
                                                                                -
                                                                              • Turns on the ceiling light.

                                                                                -

                                                                                Returns Promise<boolean>

                                                                                  -
                                                                                • Resolves with a boolean indicating whether the light is ON (true).
                                                                                • -
                                                                                -
                                                                              • Parses the service data for WoCeilingLight.

                                                                                -

                                                                                Parameters

                                                                                • manufacturerData: Buffer

                                                                                  The manufacturer data buffer.

                                                                                  -
                                                                                • emitLog: (level: string, message: string) => void

                                                                                  The function to emit log messages.

                                                                                  -

                                                                                Returns Promise<null | ceilingLightServiceData>

                                                                                  -
                                                                                • Parsed service data or null if invalid.
                                                                                • -
                                                                                -
                                                                              • Parses the service data for WoCeilingLight Pro.

                                                                                -

                                                                                Parameters

                                                                                • manufacturerData: Buffer

                                                                                  The manufacturer data buffer.

                                                                                  -
                                                                                • emitLog: (level: string, message: string) => void

                                                                                  The function to emit log messages.

                                                                                  -

                                                                                Returns Promise<null | ceilingLightProServiceData>

                                                                                  -
                                                                                • Parsed service data or null if invalid.
                                                                                • -
                                                                                -
                                                                              +mac +name +

                                                                              Methods

                                                                              Constructors

                                                                              • Parameters

                                                                                • info: DeviceInfo
                                                                                • options: {
                                                                                      apiClient?: OpenAPIClient;
                                                                                      bleConnection?: BLEConnection;
                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                      enableCircuitBreaker?: boolean;
                                                                                      enableConnectionIntelligence?: boolean;
                                                                                      enableFallback?: boolean;
                                                                                      enableRetry?: boolean;
                                                                                      logLevel?: number;
                                                                                      preferredConnection?: ConnectionType;
                                                                                      retryConfig?: RetryConfig;
                                                                                  } = {}

                                                                                Returns WoCeilingLight

                                                                              Properties

                                                                              EFFECTS: Record<string, number> = ...

                                                                              Preset effect name to effect ID mapping

                                                                              +

                                                                              Accessors

                                                                              • get deviceType(): string

                                                                                Get device type (property accessor for convenience)

                                                                                +

                                                                                Returns string

                                                                              • get id(): string | undefined

                                                                                Get device ID (property accessor for convenience)

                                                                                +

                                                                                Returns string | undefined

                                                                              • get mac(): string | undefined

                                                                                Get MAC address (property accessor for convenience)

                                                                                +

                                                                                Returns string | undefined

                                                                              • get name(): string

                                                                                Get device name (property accessor for convenience)

                                                                                +

                                                                                Returns string

                                                                              Methods

                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                +

                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                +

                                                                                Returns a CommandResult object with device info fields.

                                                                                +

                                                                                Returns Promise<CommandResult>

                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                +

                                                                                Parameters

                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                Returns boolean

                                                                              • Register a custom fallback handler

                                                                                +

                                                                                Parameters

                                                                                • handler: FallbackHandler
                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                Returns string

                                                                              • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                +

                                                                                Parameters

                                                                                • commands: (() => Promise<boolean>)[]

                                                                                Returns Promise<boolean>

                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                +

                                                                                Parameters

                                                                                • commands: (() => Promise<boolean>)[]

                                                                                Returns Promise<boolean>

                                                                              • Set RGB color

                                                                                +

                                                                                Parameters

                                                                                • red: number
                                                                                • green: number
                                                                                • blue: number

                                                                                Returns Promise<boolean>

                                                                              • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                +

                                                                                Parameters

                                                                                • minTemp: number
                                                                                • maxTemp: number
                                                                                • temp: number

                                                                                Returns Promise<boolean>

                                                                              • Set preset light effect

                                                                                +

                                                                                Parameters

                                                                                • effectName: string
                                                                                • speed: number = 100

                                                                                Returns Promise<boolean>

                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                +

                                                                                Parameters

                                                                                • mode: string | number

                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                  +

                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                  +

                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                  +

                                                                                Returns Promise<CommandResult>

                                                                              • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                +

                                                                                Returns Promise<boolean>

                                                                              diff --git a/docs/classes/WoCirculatorFan.html b/docs/classes/WoCirculatorFan.html new file mode 100644 index 00000000..4d24d423 --- /dev/null +++ b/docs/classes/WoCirculatorFan.html @@ -0,0 +1,89 @@ +WoCirculatorFan | node-switchbot
                                                                              node-switchbot
                                                                                Preparing search index...

                                                                                Class WoCirculatorFan

                                                                                Circulator Fan Device (Battery/USB) +Reuses air purifier fan-speed control and status behavior.

                                                                                +

                                                                                Hierarchy (View Summary)

                                                                                Index

                                                                                Constructors

                                                                                • Parameters

                                                                                  • info: DeviceInfo
                                                                                  • options: {
                                                                                        apiClient?: OpenAPIClient;
                                                                                        bleConnection?: BLEConnection;
                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                        enableCircuitBreaker?: boolean;
                                                                                        enableConnectionIntelligence?: boolean;
                                                                                        enableFallback?: boolean;
                                                                                        enableRetry?: boolean;
                                                                                        logLevel?: number;
                                                                                        preferredConnection?: ConnectionType;
                                                                                        retryConfig?: RetryConfig;
                                                                                    } = {}

                                                                                  Returns WoCirculatorFan

                                                                                Accessors

                                                                                • get deviceType(): string

                                                                                  Get device type (property accessor for convenience)

                                                                                  +

                                                                                  Returns string

                                                                                • get id(): string | undefined

                                                                                  Get device ID (property accessor for convenience)

                                                                                  +

                                                                                  Returns string | undefined

                                                                                • get mac(): string | undefined

                                                                                  Get MAC address (property accessor for convenience)

                                                                                  +

                                                                                  Returns string | undefined

                                                                                • get name(): string

                                                                                  Get device name (property accessor for convenience)

                                                                                  +

                                                                                  Returns string

                                                                                Methods

                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                  +

                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                  +

                                                                                  Returns a CommandResult object with device info fields.

                                                                                  +

                                                                                  Returns Promise<CommandResult>

                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                  +

                                                                                  Parameters

                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                  Returns boolean

                                                                                • Register a custom fallback handler

                                                                                  +

                                                                                  Parameters

                                                                                  • handler: FallbackHandler
                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                  Returns string

                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                  +

                                                                                  Parameters

                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                  Returns Promise<boolean>

                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                  +

                                                                                  Parameters

                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                  Returns Promise<boolean>

                                                                                • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                                                  +

                                                                                  Parameters

                                                                                  • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                                                  Returns Promise<boolean>

                                                                                diff --git a/docs/classes/WoClimatePanel.html b/docs/classes/WoClimatePanel.html new file mode 100644 index 00000000..305e128d --- /dev/null +++ b/docs/classes/WoClimatePanel.html @@ -0,0 +1,89 @@ +WoClimatePanel | node-switchbot
                                                                                node-switchbot
                                                                                  Preparing search index...

                                                                                  Class WoClimatePanel

                                                                                  Climate Panel Device +Reuses climate control behavior for power, mode, and fan-speed style control.

                                                                                  +

                                                                                  Hierarchy (View Summary)

                                                                                  Index

                                                                                  Constructors

                                                                                  • Parameters

                                                                                    • info: DeviceInfo
                                                                                    • options: {
                                                                                          apiClient?: OpenAPIClient;
                                                                                          bleConnection?: BLEConnection;
                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                          enableCircuitBreaker?: boolean;
                                                                                          enableConnectionIntelligence?: boolean;
                                                                                          enableFallback?: boolean;
                                                                                          enableRetry?: boolean;
                                                                                          logLevel?: number;
                                                                                          preferredConnection?: ConnectionType;
                                                                                          retryConfig?: RetryConfig;
                                                                                      } = {}

                                                                                    Returns WoClimatePanel

                                                                                  Accessors

                                                                                  • get deviceType(): string

                                                                                    Get device type (property accessor for convenience)

                                                                                    +

                                                                                    Returns string

                                                                                  • get id(): string | undefined

                                                                                    Get device ID (property accessor for convenience)

                                                                                    +

                                                                                    Returns string | undefined

                                                                                  • get mac(): string | undefined

                                                                                    Get MAC address (property accessor for convenience)

                                                                                    +

                                                                                    Returns string | undefined

                                                                                  • get name(): string

                                                                                    Get device name (property accessor for convenience)

                                                                                    +

                                                                                    Returns string

                                                                                  Methods

                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                    +

                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                    +

                                                                                    Returns a CommandResult object with device info fields.

                                                                                    +

                                                                                    Returns Promise<CommandResult>

                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                    +

                                                                                    Parameters

                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                    Returns boolean

                                                                                  • Register a custom fallback handler

                                                                                    +

                                                                                    Parameters

                                                                                    • handler: FallbackHandler
                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                    Returns string

                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                    +

                                                                                    Parameters

                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                    Returns Promise<boolean>

                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                    +

                                                                                    Parameters

                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                    Returns Promise<boolean>

                                                                                  • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                                                    +

                                                                                    Parameters

                                                                                    • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                                                    Returns Promise<boolean>

                                                                                  diff --git a/docs/classes/WoContact.html b/docs/classes/WoContact.html index e2388be6..6ca388a4 100644 --- a/docs/classes/WoContact.html +++ b/docs/classes/WoContact.html @@ -1,52 +1,82 @@ -WoContact | node-switchbot
                                                                                  node-switchbot
                                                                                    Preparing search index...

                                                                                    Class WoContact

                                                                                    Class representing a WoContact device.

                                                                                    -

                                                                                    Hierarchy (View Summary)

                                                                                    Index

                                                                                    Constructors

                                                                                    Accessors

                                                                                    address -connectionState -friendlyName +WoContact | node-switchbot
                                                                                    node-switchbot
                                                                                      Preparing search index...

                                                                                      Class WoContact

                                                                                      Contact Sensor (Door/Window Sensor)

                                                                                      +

                                                                                      Hierarchy (View Summary)

                                                                                      Index

                                                                                      Constructors

                                                                                      Accessors

                                                                                      • get address(): string

                                                                                        Returns string

                                                                                      • get connectionState(): string

                                                                                        Returns string

                                                                                      • get id(): string

                                                                                        Returns string

                                                                                      • get onConnectHandler(): () => Promise<void>

                                                                                        Returns () => Promise<void>

                                                                                      • set onConnectHandler(func: () => Promise<void>): void

                                                                                        Parameters

                                                                                        • func: () => Promise<void>

                                                                                        Returns void

                                                                                      • get onDisconnectHandler(): () => Promise<void>

                                                                                        Returns () => Promise<void>

                                                                                      • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                        Parameters

                                                                                        • func: () => Promise<void>

                                                                                        Returns void

                                                                                      Methods

                                                                                      • Sends a command to the device and awaits a response.

                                                                                        -

                                                                                        Parameters

                                                                                        • reqBuf: Buffer

                                                                                          The command buffer.

                                                                                          -

                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                        A Promise that resolves with the response buffer.

                                                                                        -
                                                                                      • Internal method to handle the connection process.

                                                                                        -

                                                                                        Returns Promise<void>

                                                                                        A Promise that resolves when the connection is complete.

                                                                                        -
                                                                                      • Logs a message with the specified log level.

                                                                                        -

                                                                                        Parameters

                                                                                        • level: string

                                                                                          The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                          -
                                                                                        • message: string

                                                                                          The log message to be emitted.

                                                                                          -

                                                                                        Returns Promise<void>

                                                                                      • Sets the device name.

                                                                                        -

                                                                                        Parameters

                                                                                        • name: string

                                                                                          The new device name.

                                                                                          -

                                                                                        Returns Promise<void>

                                                                                        A Promise that resolves when the name is set.

                                                                                        -
                                                                                      • Parses the service data for WoContact.

                                                                                        -

                                                                                        Parameters

                                                                                        • serviceData: Buffer

                                                                                          The service data buffer.

                                                                                          -
                                                                                        • emitLog: (level: string, message: string) => void

                                                                                          The function to emit log messages.

                                                                                          -

                                                                                        Returns Promise<null | contactSensorServiceData>

                                                                                          -
                                                                                        • Parsed service data or null if invalid.
                                                                                        • -
                                                                                        -
                                                                                      +mac +name +

                                                                                      Methods

                                                                                      Constructors

                                                                                      • Parameters

                                                                                        • info: DeviceInfo
                                                                                        • options: {
                                                                                              apiClient?: OpenAPIClient;
                                                                                              bleConnection?: BLEConnection;
                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                              enableCircuitBreaker?: boolean;
                                                                                              enableConnectionIntelligence?: boolean;
                                                                                              enableFallback?: boolean;
                                                                                              enableRetry?: boolean;
                                                                                              logLevel?: number;
                                                                                              preferredConnection?: ConnectionType;
                                                                                              retryConfig?: RetryConfig;
                                                                                          } = {}

                                                                                        Returns WoContact

                                                                                      Accessors

                                                                                      • get deviceType(): string

                                                                                        Get device type (property accessor for convenience)

                                                                                        +

                                                                                        Returns string

                                                                                      • get id(): string | undefined

                                                                                        Get device ID (property accessor for convenience)

                                                                                        +

                                                                                        Returns string | undefined

                                                                                      • get mac(): string | undefined

                                                                                        Get MAC address (property accessor for convenience)

                                                                                        +

                                                                                        Returns string | undefined

                                                                                      • get name(): string

                                                                                        Get device name (property accessor for convenience)

                                                                                        +

                                                                                        Returns string

                                                                                      Methods

                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                        +

                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                        +

                                                                                        Returns a CommandResult object with device info fields.

                                                                                        +

                                                                                        Returns Promise<CommandResult>

                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                        +

                                                                                        Parameters

                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                        Returns boolean

                                                                                      • Register a custom fallback handler

                                                                                        +

                                                                                        Parameters

                                                                                        • handler: FallbackHandler
                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                        Returns string

                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                        +

                                                                                        Parameters

                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                        Returns Promise<boolean>

                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                        +

                                                                                        Parameters

                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                        Returns Promise<boolean>

                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                        +

                                                                                        Parameters

                                                                                        • mode: string | number

                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                          +

                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                          +

                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                          +

                                                                                        Returns Promise<CommandResult>

                                                                                      diff --git a/docs/classes/WoCurtain.html b/docs/classes/WoCurtain.html index 38f2c86f..2306ecc8 100644 --- a/docs/classes/WoCurtain.html +++ b/docs/classes/WoCurtain.html @@ -1,72 +1,94 @@ -WoCurtain | node-switchbot
                                                                                      node-switchbot
                                                                                        Preparing search index...

                                                                                        Class WoCurtain

                                                                                        Class representing a WoCurtain device.

                                                                                        -

                                                                                        Hierarchy (View Summary)

                                                                                        Index

                                                                                        Constructors

                                                                                        Accessors

                                                                                        address -connectionState -friendlyName +WoCurtain | node-switchbot
                                                                                        node-switchbot
                                                                                          Preparing search index...

                                                                                          Class WoCurtain

                                                                                          Curtain Device - Smart curtain controller

                                                                                          +

                                                                                          Hierarchy (View Summary)

                                                                                          Implements

                                                                                          Index

                                                                                          Constructors

                                                                                          Accessors

                                                                                          • get address(): string

                                                                                            Returns string

                                                                                          • get connectionState(): string

                                                                                            Returns string

                                                                                          • get id(): string

                                                                                            Returns string

                                                                                          • get onConnectHandler(): () => Promise<void>

                                                                                            Returns () => Promise<void>

                                                                                          • set onConnectHandler(func: () => Promise<void>): void

                                                                                            Parameters

                                                                                            • func: () => Promise<void>

                                                                                            Returns void

                                                                                          • get onDisconnectHandler(): () => Promise<void>

                                                                                            Returns () => Promise<void>

                                                                                          • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                            Parameters

                                                                                            • func: () => Promise<void>

                                                                                            Returns void

                                                                                          Methods

                                                                                          • Closes the curtain.

                                                                                            -

                                                                                            Parameters

                                                                                            • Optionalmode: number = 0xFF

                                                                                              Running mode (0x01 = QuietDrift, 0xFF = Default).

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                          • Sends a command to the device and awaits a response.

                                                                                            -

                                                                                            Parameters

                                                                                            • reqBuf: Buffer

                                                                                              The command buffer.

                                                                                              -

                                                                                            Returns Promise<Buffer<ArrayBufferLike>>

                                                                                            A Promise that resolves with the response buffer.

                                                                                            -
                                                                                          • Internal method to handle the connection process.

                                                                                            -

                                                                                            Returns Promise<void>

                                                                                            A Promise that resolves when the connection is complete.

                                                                                            -
                                                                                          • Logs a message with the specified log level.

                                                                                            -

                                                                                            Parameters

                                                                                            • level: string

                                                                                              The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                              -
                                                                                            • message: string

                                                                                              The log message to be emitted.

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                          • Opens the curtain.

                                                                                            -

                                                                                            Parameters

                                                                                            • Optionalmode: number = 0xFF

                                                                                              Running mode (0x01 = QuietDrift, 0xFF = Default).

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                          • Sends a command to the curtain.

                                                                                            -

                                                                                            Parameters

                                                                                            • bytes: number[]

                                                                                              The command bytes.

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                          • Pauses the curtain.

                                                                                            -

                                                                                            Returns Promise<void>

                                                                                          • Runs the curtain to the target position.

                                                                                            -

                                                                                            Parameters

                                                                                            • percent: number

                                                                                              The percentage of the target position.

                                                                                              -
                                                                                            • Optionalmode: number = 0xFF

                                                                                              Running mode (0x01 = QuietDrift, 0xFF = Default).

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                          • Sets the device name.

                                                                                            -

                                                                                            Parameters

                                                                                            • name: string

                                                                                              The new device name.

                                                                                              -

                                                                                            Returns Promise<void>

                                                                                            A Promise that resolves when the name is set.

                                                                                            -
                                                                                          • Parses the service data for WoCurtain.

                                                                                            -

                                                                                            Parameters

                                                                                            • serviceData: Buffer

                                                                                              The service data buffer.

                                                                                              -
                                                                                            • manufacturerData: Buffer

                                                                                              The manufacturer data buffer.

                                                                                              -
                                                                                            • emitLog: (level: string, message: string) => void

                                                                                              The function to emit log messages.

                                                                                              -
                                                                                            • Optionalreverse: boolean = false

                                                                                              Whether to reverse the position.

                                                                                              -

                                                                                            Returns Promise<null | curtainServiceData | curtain3ServiceData>

                                                                                              -
                                                                                            • Parsed service data or null if invalid.
                                                                                            • -
                                                                                            -
                                                                                          +pollIfNeeded +pollNeeded +registerFallbackHandler +sendCommandSequence +sendMultipleCommands +setCircuitBreakerEnabled +setConnectionIntelligenceEnabled +setFallbackEnabled +setMode +setPosition +setPreferredConnection +setRetryEnabled +unregisterFallbackHandler +updateInfo +

                                                                                          Constructors

                                                                                          • Parameters

                                                                                            • info: DeviceInfo
                                                                                            • options: {
                                                                                                  apiClient?: OpenAPIClient;
                                                                                                  bleConnection?: BLEConnection;
                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                  enableFallback?: boolean;
                                                                                                  enableRetry?: boolean;
                                                                                                  logLevel?: number;
                                                                                                  preferredConnection?: ConnectionType;
                                                                                                  retryConfig?: RetryConfig;
                                                                                              } = {}

                                                                                            Returns WoCurtain

                                                                                          Properties

                                                                                          _lastPosition?: number

                                                                                          Get device status

                                                                                          +

                                                                                          Accessors

                                                                                          • get deviceType(): string

                                                                                            Get device type (property accessor for convenience)

                                                                                            +

                                                                                            Returns string

                                                                                          • get id(): string | undefined

                                                                                            Get device ID (property accessor for convenience)

                                                                                            +

                                                                                            Returns string | undefined

                                                                                          • get mac(): string | undefined

                                                                                            Get MAC address (property accessor for convenience)

                                                                                            +

                                                                                            Returns string | undefined

                                                                                          • get name(): string

                                                                                            Get device name (property accessor for convenience)

                                                                                            +

                                                                                            Returns string

                                                                                          Methods

                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                            +

                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                            +

                                                                                            Returns a CommandResult object with device info fields.

                                                                                            +

                                                                                            Returns Promise<CommandResult>

                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                            +

                                                                                            Parameters

                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                            Returns boolean

                                                                                          • Register a custom fallback handler

                                                                                            +

                                                                                            Parameters

                                                                                            • handler: FallbackHandler
                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                            Returns string

                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                            +

                                                                                            Parameters

                                                                                            • mode: string | number

                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                              +

                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                              +

                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                              +

                                                                                            Returns Promise<CommandResult>

                                                                                          diff --git a/docs/classes/WoFloorLamp.html b/docs/classes/WoFloorLamp.html new file mode 100644 index 00000000..1e1e0a88 --- /dev/null +++ b/docs/classes/WoFloorLamp.html @@ -0,0 +1,103 @@ +WoFloorLamp | node-switchbot
                                                                                          node-switchbot
                                                                                            Preparing search index...

                                                                                            Class WoFloorLamp

                                                                                            Floor Lamp Device +Uses same logic as Color Bulb

                                                                                            +

                                                                                            Hierarchy (View Summary)

                                                                                            Index

                                                                                            Constructors

                                                                                            • Parameters

                                                                                              • info: DeviceInfo
                                                                                              • options: {
                                                                                                    apiClient?: OpenAPIClient;
                                                                                                    bleConnection?: BLEConnection;
                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                    enableFallback?: boolean;
                                                                                                    enableRetry?: boolean;
                                                                                                    logLevel?: number;
                                                                                                    preferredConnection?: ConnectionType;
                                                                                                    retryConfig?: RetryConfig;
                                                                                                } = {}

                                                                                              Returns WoFloorLamp

                                                                                            Properties

                                                                                            EFFECTS: Record<string, number> = ...

                                                                                            Preset effect name to effect ID mapping

                                                                                            +

                                                                                            Accessors

                                                                                            • get deviceType(): string

                                                                                              Get device type (property accessor for convenience)

                                                                                              +

                                                                                              Returns string

                                                                                            • get id(): string | undefined

                                                                                              Get device ID (property accessor for convenience)

                                                                                              +

                                                                                              Returns string | undefined

                                                                                            • get mac(): string | undefined

                                                                                              Get MAC address (property accessor for convenience)

                                                                                              +

                                                                                              Returns string | undefined

                                                                                            • get name(): string

                                                                                              Get device name (property accessor for convenience)

                                                                                              +

                                                                                              Returns string

                                                                                            Methods

                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                              +

                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                              +

                                                                                              Returns a CommandResult object with device info fields.

                                                                                              +

                                                                                              Returns Promise<CommandResult>

                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                              +

                                                                                              Parameters

                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                              Returns boolean

                                                                                            • Register a custom fallback handler

                                                                                              +

                                                                                              Parameters

                                                                                              • handler: FallbackHandler
                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                              Returns string

                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                              +

                                                                                              Parameters

                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                              Returns Promise<boolean>

                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                              +

                                                                                              Parameters

                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                              Returns Promise<boolean>

                                                                                            • Set RGB color

                                                                                              +

                                                                                              Parameters

                                                                                              • red: number
                                                                                              • green: number
                                                                                              • blue: number

                                                                                              Returns Promise<boolean>

                                                                                            • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                              +

                                                                                              Parameters

                                                                                              • minTemp: number
                                                                                              • maxTemp: number
                                                                                              • temp: number

                                                                                              Returns Promise<boolean>

                                                                                            • Set preset light effect

                                                                                              +

                                                                                              Parameters

                                                                                              • effectName: string
                                                                                              • speed: number = 100

                                                                                              Returns Promise<boolean>

                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                              +

                                                                                              Parameters

                                                                                              • mode: string | number

                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                +

                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                +

                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                +

                                                                                              Returns Promise<CommandResult>

                                                                                            • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                              +

                                                                                              Returns Promise<boolean>

                                                                                            diff --git a/docs/classes/WoGarageDoorOpener.html b/docs/classes/WoGarageDoorOpener.html new file mode 100644 index 00000000..57095047 --- /dev/null +++ b/docs/classes/WoGarageDoorOpener.html @@ -0,0 +1,94 @@ +WoGarageDoorOpener | node-switchbot
                                                                                            node-switchbot
                                                                                              Preparing search index...

                                                                                              Class WoGarageDoorOpener

                                                                                              Garage Door Opener Device (uses relay switch control) +Extends Relay Switch 1 for simple open/close control

                                                                                              +

                                                                                              Hierarchy (View Summary)

                                                                                              Index

                                                                                              Constructors

                                                                                              • Parameters

                                                                                                • info: DeviceInfo
                                                                                                • options: {
                                                                                                      apiClient?: OpenAPIClient;
                                                                                                      bleConnection?: BLEConnection;
                                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                      enableCircuitBreaker?: boolean;
                                                                                                      enableConnectionIntelligence?: boolean;
                                                                                                      enableFallback?: boolean;
                                                                                                      enableRetry?: boolean;
                                                                                                      logLevel?: number;
                                                                                                      preferredConnection?: ConnectionType;
                                                                                                      retryConfig?: RetryConfig;
                                                                                                  } = {}

                                                                                                Returns WoGarageDoorOpener

                                                                                              Accessors

                                                                                              • get deviceType(): string

                                                                                                Get device type (property accessor for convenience)

                                                                                                +

                                                                                                Returns string

                                                                                              • get id(): string | undefined

                                                                                                Get device ID (property accessor for convenience)

                                                                                                +

                                                                                                Returns string | undefined

                                                                                              • get mac(): string | undefined

                                                                                                Get MAC address (property accessor for convenience)

                                                                                                +

                                                                                                Returns string | undefined

                                                                                              • get name(): string

                                                                                                Get device name (property accessor for convenience)

                                                                                                +

                                                                                                Returns string

                                                                                              Methods

                                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                +

                                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                +

                                                                                                Returns a CommandResult object with device info fields.

                                                                                                +

                                                                                                Returns Promise<CommandResult>

                                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                +

                                                                                                Parameters

                                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                Returns boolean

                                                                                              • Register a custom fallback handler

                                                                                                +

                                                                                                Parameters

                                                                                                • handler: FallbackHandler
                                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                                Returns string

                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                +

                                                                                                Parameters

                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                Returns Promise<boolean>

                                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                +

                                                                                                Parameters

                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                Returns Promise<boolean>

                                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                +

                                                                                                Parameters

                                                                                                • mode: string | number

                                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                                  +

                                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                  +

                                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                                  +

                                                                                                Returns Promise<CommandResult>

                                                                                              diff --git a/docs/classes/WoHand.html b/docs/classes/WoHand.html index ddb04ff4..c8e8cc62 100644 --- a/docs/classes/WoHand.html +++ b/docs/classes/WoHand.html @@ -1,62 +1,95 @@ -WoHand | node-switchbot
                                                                                              node-switchbot
                                                                                                Preparing search index...

                                                                                                Class WoHand

                                                                                                Class representing a WoHand device.

                                                                                                -

                                                                                                Hierarchy (View Summary)

                                                                                                Index

                                                                                                Constructors

                                                                                                Accessors

                                                                                                address -connectionState -friendlyName +WoHand | node-switchbot
                                                                                                node-switchbot
                                                                                                  Preparing search index...

                                                                                                  Class WoHand

                                                                                                  Bot (WoHand) Device - Press or switch button device +Supports optional BLE password protection

                                                                                                  +

                                                                                                  Hierarchy (View Summary)

                                                                                                  Implements

                                                                                                  Index

                                                                                                  Constructors

                                                                                                  Accessors

                                                                                                  • get address(): string

                                                                                                    Returns string

                                                                                                  • get connectionState(): string

                                                                                                    Returns string

                                                                                                  • get id(): string

                                                                                                    Returns string

                                                                                                  • get onConnectHandler(): () => Promise<void>

                                                                                                    Returns () => Promise<void>

                                                                                                  • set onConnectHandler(func: () => Promise<void>): void

                                                                                                    Parameters

                                                                                                    • func: () => Promise<void>

                                                                                                    Returns void

                                                                                                  • get onDisconnectHandler(): () => Promise<void>

                                                                                                    Returns () => Promise<void>

                                                                                                  • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                    Parameters

                                                                                                    • func: () => Promise<void>

                                                                                                    Returns void

                                                                                                  Methods

                                                                                                  • Sends a command to the device and awaits a response.

                                                                                                    -

                                                                                                    Parameters

                                                                                                    • reqBuf: Buffer

                                                                                                      The command buffer.

                                                                                                      -

                                                                                                    Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                    A Promise that resolves with the response buffer.

                                                                                                    -
                                                                                                  • Moves the bot down.

                                                                                                    -

                                                                                                    Returns Promise<void>

                                                                                                  • Internal method to handle the connection process.

                                                                                                    -

                                                                                                    Returns Promise<void>

                                                                                                    A Promise that resolves when the connection is complete.

                                                                                                    -
                                                                                                  • Logs a message with the specified log level.

                                                                                                    -

                                                                                                    Parameters

                                                                                                    • level: string

                                                                                                      The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                      -
                                                                                                    • message: string

                                                                                                      The log message to be emitted.

                                                                                                      -

                                                                                                    Returns Promise<void>

                                                                                                  • Presses the bot.

                                                                                                    -

                                                                                                    Returns Promise<void>

                                                                                                  • Sets the device name.

                                                                                                    -

                                                                                                    Parameters

                                                                                                    • name: string

                                                                                                      The new device name.

                                                                                                      -

                                                                                                    Returns Promise<void>

                                                                                                    A Promise that resolves when the name is set.

                                                                                                    -
                                                                                                  • Turns off the bot.

                                                                                                    -

                                                                                                    Returns Promise<void>

                                                                                                  • Turns on the bot.

                                                                                                    -

                                                                                                    Returns Promise<void>

                                                                                                  • Parses the service data for WoHand.

                                                                                                    -

                                                                                                    Parameters

                                                                                                    • serviceData: Buffer

                                                                                                      The service data buffer.

                                                                                                      -
                                                                                                    • emitLog: (level: string, message: string) => void

                                                                                                      The function to emit log messages.

                                                                                                      -

                                                                                                    Returns Promise<null | botServiceData>

                                                                                                      -
                                                                                                    • Parsed service data or null if invalid.
                                                                                                    • -
                                                                                                    -
                                                                                                  +unregisterFallbackHandler +updateInfo +

                                                                                                  Constructors

                                                                                                  • Parameters

                                                                                                    • info: DeviceInfo
                                                                                                    • options: {
                                                                                                          apiClient?: OpenAPIClient;
                                                                                                          bleConnection?: BLEConnection;
                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                          enableFallback?: boolean;
                                                                                                          enableRetry?: boolean;
                                                                                                          logLevel?: number;
                                                                                                          password?: string;
                                                                                                          preferredConnection?: "ble" | "api";
                                                                                                      } = {}

                                                                                                    Returns WoHand

                                                                                                  Accessors

                                                                                                  • get activeConnection(): ConnectionType | undefined

                                                                                                    Get active connection type (property accessor for convenience)

                                                                                                    +

                                                                                                    Returns ConnectionType | undefined

                                                                                                  • get deviceType(): string

                                                                                                    Get device type (property accessor for convenience)

                                                                                                    +

                                                                                                    Returns string

                                                                                                  • get id(): string | undefined

                                                                                                    Get device ID (property accessor for convenience)

                                                                                                    +

                                                                                                    Returns string | undefined

                                                                                                  • get mac(): string | undefined

                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                    +

                                                                                                    Returns string | undefined

                                                                                                  • get name(): string

                                                                                                    Get device name (property accessor for convenience)

                                                                                                    +

                                                                                                    Returns string

                                                                                                  Methods

                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                    +

                                                                                                    Parameters

                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                    Returns Promise<boolean>

                                                                                                  • Set or update Bot password

                                                                                                    +

                                                                                                    Parameters

                                                                                                    • password: string

                                                                                                      4-character alphanumeric password (case-sensitive)

                                                                                                      +

                                                                                                    Returns void

                                                                                                  diff --git a/docs/classes/WoHub2.html b/docs/classes/WoHub2.html index 2bada686..e2ca37f6 100644 --- a/docs/classes/WoHub2.html +++ b/docs/classes/WoHub2.html @@ -1,52 +1,82 @@ -WoHub2 | node-switchbot
                                                                                                  node-switchbot
                                                                                                    Preparing search index...

                                                                                                    Class WoHub2

                                                                                                    Class representing a WoHub2 device.

                                                                                                    -

                                                                                                    Hierarchy (View Summary)

                                                                                                    Index

                                                                                                    Constructors

                                                                                                    Accessors

                                                                                                    address -connectionState -friendlyName +WoHub2 | node-switchbot
                                                                                                    node-switchbot
                                                                                                      Preparing search index...

                                                                                                      Class WoHub2

                                                                                                      Hub 2 Device (Hub Mini/Hub Plus also use this)

                                                                                                      +

                                                                                                      Hierarchy (View Summary)

                                                                                                      Index

                                                                                                      Constructors

                                                                                                      Accessors

                                                                                                      • get address(): string

                                                                                                        Returns string

                                                                                                      • get connectionState(): string

                                                                                                        Returns string

                                                                                                      • get id(): string

                                                                                                        Returns string

                                                                                                      • get onConnectHandler(): () => Promise<void>

                                                                                                        Returns () => Promise<void>

                                                                                                      • set onConnectHandler(func: () => Promise<void>): void

                                                                                                        Parameters

                                                                                                        • func: () => Promise<void>

                                                                                                        Returns void

                                                                                                      • get onDisconnectHandler(): () => Promise<void>

                                                                                                        Returns () => Promise<void>

                                                                                                      • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                        Parameters

                                                                                                        • func: () => Promise<void>

                                                                                                        Returns void

                                                                                                      Methods

                                                                                                      • Sends a command to the device and awaits a response.

                                                                                                        -

                                                                                                        Parameters

                                                                                                        • reqBuf: Buffer

                                                                                                          The command buffer.

                                                                                                          -

                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                        A Promise that resolves with the response buffer.

                                                                                                        -
                                                                                                      • Internal method to handle the connection process.

                                                                                                        -

                                                                                                        Returns Promise<void>

                                                                                                        A Promise that resolves when the connection is complete.

                                                                                                        -
                                                                                                      • Logs a message with the specified log level.

                                                                                                        -

                                                                                                        Parameters

                                                                                                        • level: string

                                                                                                          The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                          -
                                                                                                        • message: string

                                                                                                          The log message to be emitted.

                                                                                                          -

                                                                                                        Returns Promise<void>

                                                                                                      • Sets the device name.

                                                                                                        -

                                                                                                        Parameters

                                                                                                        • name: string

                                                                                                          The new device name.

                                                                                                          -

                                                                                                        Returns Promise<void>

                                                                                                        A Promise that resolves when the name is set.

                                                                                                        -
                                                                                                      • Parses the service data for WoHub2.

                                                                                                        -

                                                                                                        Parameters

                                                                                                        • manufacturerData: Buffer

                                                                                                          The manufacturer data buffer.

                                                                                                          -
                                                                                                        • emitLog: (level: string, message: string) => void

                                                                                                          The function to emit log messages.

                                                                                                          -

                                                                                                        Returns Promise<null | hub2ServiceData>

                                                                                                          -
                                                                                                        • Parsed service data or null if invalid.
                                                                                                        • -
                                                                                                        -
                                                                                                      +mac +name +

                                                                                                      Methods

                                                                                                      Constructors

                                                                                                      • Parameters

                                                                                                        • info: DeviceInfo
                                                                                                        • options: {
                                                                                                              apiClient?: OpenAPIClient;
                                                                                                              bleConnection?: BLEConnection;
                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                              enableFallback?: boolean;
                                                                                                              enableRetry?: boolean;
                                                                                                              logLevel?: number;
                                                                                                              preferredConnection?: ConnectionType;
                                                                                                              retryConfig?: RetryConfig;
                                                                                                          } = {}

                                                                                                        Returns WoHub2

                                                                                                      Accessors

                                                                                                      • get deviceType(): string

                                                                                                        Get device type (property accessor for convenience)

                                                                                                        +

                                                                                                        Returns string

                                                                                                      • get id(): string | undefined

                                                                                                        Get device ID (property accessor for convenience)

                                                                                                        +

                                                                                                        Returns string | undefined

                                                                                                      • get mac(): string | undefined

                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                        +

                                                                                                        Returns string | undefined

                                                                                                      • get name(): string

                                                                                                        Get device name (property accessor for convenience)

                                                                                                        +

                                                                                                        Returns string

                                                                                                      Methods

                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                        +

                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                        +

                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                        +

                                                                                                        Returns Promise<CommandResult>

                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                        +

                                                                                                        Parameters

                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                        Returns boolean

                                                                                                      • Register a custom fallback handler

                                                                                                        +

                                                                                                        Parameters

                                                                                                        • handler: FallbackHandler
                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                        Returns string

                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                        +

                                                                                                        Parameters

                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                        Returns Promise<boolean>

                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                        +

                                                                                                        Parameters

                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                        Returns Promise<boolean>

                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                        +

                                                                                                        Parameters

                                                                                                        • mode: string | number

                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                          +

                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                          +

                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                          +

                                                                                                        Returns Promise<CommandResult>

                                                                                                      diff --git a/docs/classes/WoHub3.html b/docs/classes/WoHub3.html index 0fcc81ae..d01a189c 100644 --- a/docs/classes/WoHub3.html +++ b/docs/classes/WoHub3.html @@ -1,52 +1,83 @@ -WoHub3 | node-switchbot
                                                                                                      node-switchbot
                                                                                                        Preparing search index...

                                                                                                        Class WoHub3

                                                                                                        Class representing a WoHub3 device.

                                                                                                        -

                                                                                                        Hierarchy (View Summary)

                                                                                                        Index

                                                                                                        Constructors

                                                                                                        Accessors

                                                                                                        address -connectionState -friendlyName +WoHub3 | node-switchbot
                                                                                                        node-switchbot
                                                                                                          Preparing search index...

                                                                                                          Class WoHub3

                                                                                                          Hub 3 Device +Uses same logic as Hub 2

                                                                                                          +

                                                                                                          Hierarchy (View Summary)

                                                                                                          Index

                                                                                                          Constructors

                                                                                                          Accessors

                                                                                                          • get address(): string

                                                                                                            Returns string

                                                                                                          • get connectionState(): string

                                                                                                            Returns string

                                                                                                          • get id(): string

                                                                                                            Returns string

                                                                                                          • get onConnectHandler(): () => Promise<void>

                                                                                                            Returns () => Promise<void>

                                                                                                          • set onConnectHandler(func: () => Promise<void>): void

                                                                                                            Parameters

                                                                                                            • func: () => Promise<void>

                                                                                                            Returns void

                                                                                                          • get onDisconnectHandler(): () => Promise<void>

                                                                                                            Returns () => Promise<void>

                                                                                                          • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                            Parameters

                                                                                                            • func: () => Promise<void>

                                                                                                            Returns void

                                                                                                          Methods

                                                                                                          • Sends a command to the device and awaits a response.

                                                                                                            -

                                                                                                            Parameters

                                                                                                            • reqBuf: Buffer

                                                                                                              The command buffer.

                                                                                                              -

                                                                                                            Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                            A Promise that resolves with the response buffer.

                                                                                                            -
                                                                                                          • Internal method to handle the connection process.

                                                                                                            -

                                                                                                            Returns Promise<void>

                                                                                                            A Promise that resolves when the connection is complete.

                                                                                                            -
                                                                                                          • Logs a message with the specified log level.

                                                                                                            -

                                                                                                            Parameters

                                                                                                            • level: string

                                                                                                              The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                              -
                                                                                                            • message: string

                                                                                                              The log message to be emitted.

                                                                                                              -

                                                                                                            Returns Promise<void>

                                                                                                          • Sets the device name.

                                                                                                            -

                                                                                                            Parameters

                                                                                                            • name: string

                                                                                                              The new device name.

                                                                                                              -

                                                                                                            Returns Promise<void>

                                                                                                            A Promise that resolves when the name is set.

                                                                                                            -
                                                                                                          • Parses the service data for WoHub3.

                                                                                                            -

                                                                                                            Parameters

                                                                                                            • manufacturerData: Buffer

                                                                                                              The manufacturer data buffer.

                                                                                                              -
                                                                                                            • emitLog: (level: string, message: string) => void

                                                                                                              The function to emit log messages.

                                                                                                              -

                                                                                                            Returns Promise<null | hub3ServiceData>

                                                                                                              -
                                                                                                            • Parsed service data or null if invalid.
                                                                                                            • -
                                                                                                            -
                                                                                                          +mac +name +

                                                                                                          Methods

                                                                                                          Constructors

                                                                                                          • Parameters

                                                                                                            • info: DeviceInfo
                                                                                                            • options: {
                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                  enableFallback?: boolean;
                                                                                                                  enableRetry?: boolean;
                                                                                                                  logLevel?: number;
                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                  retryConfig?: RetryConfig;
                                                                                                              } = {}

                                                                                                            Returns WoHub3

                                                                                                          Accessors

                                                                                                          • get deviceType(): string

                                                                                                            Get device type (property accessor for convenience)

                                                                                                            +

                                                                                                            Returns string

                                                                                                          • get id(): string | undefined

                                                                                                            Get device ID (property accessor for convenience)

                                                                                                            +

                                                                                                            Returns string | undefined

                                                                                                          • get mac(): string | undefined

                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                            +

                                                                                                            Returns string | undefined

                                                                                                          • get name(): string

                                                                                                            Get device name (property accessor for convenience)

                                                                                                            +

                                                                                                            Returns string

                                                                                                          Methods

                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                            +

                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                            +

                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                            +

                                                                                                            Returns Promise<CommandResult>

                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                            +

                                                                                                            Parameters

                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                            Returns boolean

                                                                                                          • Register a custom fallback handler

                                                                                                            +

                                                                                                            Parameters

                                                                                                            • handler: FallbackHandler
                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                            Returns string

                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                            +

                                                                                                            Parameters

                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                            Returns Promise<boolean>

                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                            +

                                                                                                            Parameters

                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                            Returns Promise<boolean>

                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                            +

                                                                                                            Parameters

                                                                                                            • mode: string | number

                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                              +

                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                              +

                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                              +

                                                                                                            Returns Promise<CommandResult>

                                                                                                          diff --git a/docs/classes/WoHubMiniMatter.html b/docs/classes/WoHubMiniMatter.html new file mode 100644 index 00000000..0a7f72e9 --- /dev/null +++ b/docs/classes/WoHubMiniMatter.html @@ -0,0 +1,83 @@ +WoHubMiniMatter | node-switchbot
                                                                                                          node-switchbot
                                                                                                            Preparing search index...

                                                                                                            Class WoHubMiniMatter

                                                                                                            HubMini Matter Device +Uses same hub logic as Hub 2

                                                                                                            +

                                                                                                            Hierarchy (View Summary)

                                                                                                            Index

                                                                                                            Constructors

                                                                                                            • Parameters

                                                                                                              • info: DeviceInfo
                                                                                                              • options: {
                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                    enableFallback?: boolean;
                                                                                                                    enableRetry?: boolean;
                                                                                                                    logLevel?: number;
                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                } = {}

                                                                                                              Returns WoHubMiniMatter

                                                                                                            Accessors

                                                                                                            • get deviceType(): string

                                                                                                              Get device type (property accessor for convenience)

                                                                                                              +

                                                                                                              Returns string

                                                                                                            • get id(): string | undefined

                                                                                                              Get device ID (property accessor for convenience)

                                                                                                              +

                                                                                                              Returns string | undefined

                                                                                                            • get mac(): string | undefined

                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                              +

                                                                                                              Returns string | undefined

                                                                                                            • get name(): string

                                                                                                              Get device name (property accessor for convenience)

                                                                                                              +

                                                                                                              Returns string

                                                                                                            Methods

                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                              +

                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                              +

                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                              +

                                                                                                              Returns Promise<CommandResult>

                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                              +

                                                                                                              Parameters

                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                              Returns boolean

                                                                                                            • Register a custom fallback handler

                                                                                                              +

                                                                                                              Parameters

                                                                                                              • handler: FallbackHandler
                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                              Returns string

                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                              +

                                                                                                              Parameters

                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                              Returns Promise<boolean>

                                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                              +

                                                                                                              Parameters

                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                              Returns Promise<boolean>

                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                              +

                                                                                                              Parameters

                                                                                                              • mode: string | number

                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                +

                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                +

                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                +

                                                                                                              Returns Promise<CommandResult>

                                                                                                            diff --git a/docs/classes/WoHumi.html b/docs/classes/WoHumi.html index a310baf6..0327efa1 100644 --- a/docs/classes/WoHumi.html +++ b/docs/classes/WoHumi.html @@ -1,67 +1,89 @@ -WoHumi | node-switchbot
                                                                                                            node-switchbot
                                                                                                              Preparing search index...

                                                                                                              Class WoHumi

                                                                                                              Class representing a WoHumi device.

                                                                                                              -

                                                                                                              Hierarchy (View Summary)

                                                                                                              Index

                                                                                                              Constructors

                                                                                                              Accessors

                                                                                                              address -connectionState -friendlyName +WoHumi | node-switchbot
                                                                                                              node-switchbot
                                                                                                                Preparing search index...

                                                                                                                Class WoHumi

                                                                                                                Humidifier Device

                                                                                                                +

                                                                                                                Hierarchy (View Summary)

                                                                                                                Implements

                                                                                                                Index

                                                                                                                Constructors

                                                                                                                Accessors

                                                                                                                • get address(): string

                                                                                                                  Returns string

                                                                                                                • get connectionState(): string

                                                                                                                  Returns string

                                                                                                                • get id(): string

                                                                                                                  Returns string

                                                                                                                • get onConnectHandler(): () => Promise<void>

                                                                                                                  Returns () => Promise<void>

                                                                                                                • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                  Parameters

                                                                                                                  • func: () => Promise<void>

                                                                                                                  Returns void

                                                                                                                • get onDisconnectHandler(): () => Promise<void>

                                                                                                                  Returns () => Promise<void>

                                                                                                                • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                  Parameters

                                                                                                                  • func: () => Promise<void>

                                                                                                                  Returns void

                                                                                                                Methods

                                                                                                                • Sends a command to the device and awaits a response.

                                                                                                                  -

                                                                                                                  Parameters

                                                                                                                  • reqBuf: Buffer

                                                                                                                    The command buffer.

                                                                                                                    -

                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                  A Promise that resolves with the response buffer.

                                                                                                                  -
                                                                                                                • Decreases the humidifier setting.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Increases the humidifier setting.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Internal method to handle the connection process.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                  A Promise that resolves when the connection is complete.

                                                                                                                  -
                                                                                                                • Logs a message with the specified log level.

                                                                                                                  -

                                                                                                                  Parameters

                                                                                                                  • level: string

                                                                                                                    The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                    -
                                                                                                                  • message: string

                                                                                                                    The log message to be emitted.

                                                                                                                    -

                                                                                                                  Returns Promise<void>

                                                                                                                • Sets the humidifier level.

                                                                                                                  -

                                                                                                                  Parameters

                                                                                                                  • level: number

                                                                                                                    The level to set (0-100).

                                                                                                                    -

                                                                                                                  Returns Promise<void>

                                                                                                                • Sets the humidifier to auto mode.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Sets the device name.

                                                                                                                  -

                                                                                                                  Parameters

                                                                                                                  • name: string

                                                                                                                    The new device name.

                                                                                                                    -

                                                                                                                  Returns Promise<void>

                                                                                                                  A Promise that resolves when the name is set.

                                                                                                                  -
                                                                                                                • Sets the humidifier to manual mode.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Turns off the humidifier.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Turns on the humidifier.

                                                                                                                  -

                                                                                                                  Returns Promise<void>

                                                                                                                • Parses the service data for WoHumi.

                                                                                                                  -

                                                                                                                  Parameters

                                                                                                                  • serviceData: Buffer

                                                                                                                    The service data buffer.

                                                                                                                    -
                                                                                                                  • emitLog: (level: string, message: string) => void

                                                                                                                    The function to emit log messages.

                                                                                                                    -

                                                                                                                  Returns Promise<null | humidifierServiceData>

                                                                                                                    -
                                                                                                                  • Parsed service data or null if invalid.
                                                                                                                  • -
                                                                                                                  -
                                                                                                                +unregisterFallbackHandler +updateInfo +

                                                                                                                Constructors

                                                                                                                • Parameters

                                                                                                                  • info: DeviceInfo
                                                                                                                  • options: {
                                                                                                                        apiClient?: OpenAPIClient;
                                                                                                                        bleConnection?: BLEConnection;
                                                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                        enableCircuitBreaker?: boolean;
                                                                                                                        enableConnectionIntelligence?: boolean;
                                                                                                                        enableFallback?: boolean;
                                                                                                                        enableRetry?: boolean;
                                                                                                                        logLevel?: number;
                                                                                                                        preferredConnection?: ConnectionType;
                                                                                                                        retryConfig?: RetryConfig;
                                                                                                                    } = {}

                                                                                                                  Returns WoHumi

                                                                                                                Accessors

                                                                                                                • get deviceType(): string

                                                                                                                  Get device type (property accessor for convenience)

                                                                                                                  +

                                                                                                                  Returns string

                                                                                                                • get id(): string | undefined

                                                                                                                  Get device ID (property accessor for convenience)

                                                                                                                  +

                                                                                                                  Returns string | undefined

                                                                                                                • get mac(): string | undefined

                                                                                                                  Get MAC address (property accessor for convenience)

                                                                                                                  +

                                                                                                                  Returns string | undefined

                                                                                                                • get name(): string

                                                                                                                  Get device name (property accessor for convenience)

                                                                                                                  +

                                                                                                                  Returns string

                                                                                                                Methods

                                                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                  +

                                                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                  +

                                                                                                                  Returns a CommandResult object with device info fields.

                                                                                                                  +

                                                                                                                  Returns Promise<CommandResult>

                                                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                  +

                                                                                                                  Parameters

                                                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                  Returns boolean

                                                                                                                • Register a custom fallback handler

                                                                                                                  +

                                                                                                                  Parameters

                                                                                                                  • handler: FallbackHandler
                                                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                                                  Returns string

                                                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                  +

                                                                                                                  Parameters

                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                  Returns Promise<boolean>

                                                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                  +

                                                                                                                  Parameters

                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                  Returns Promise<boolean>

                                                                                                                diff --git a/docs/classes/WoHumi2.html b/docs/classes/WoHumi2.html index 1d7c8990..d7abf29d 100644 --- a/docs/classes/WoHumi2.html +++ b/docs/classes/WoHumi2.html @@ -1,67 +1,90 @@ -WoHumi2 | node-switchbot
                                                                                                                node-switchbot
                                                                                                                  Preparing search index...

                                                                                                                  Class WoHumi2

                                                                                                                  Class representing a WoHumi device.

                                                                                                                  -

                                                                                                                  Hierarchy (View Summary)

                                                                                                                  Index

                                                                                                                  Constructors

                                                                                                                  Accessors

                                                                                                                  address -connectionState -friendlyName +WoHumi2 | node-switchbot
                                                                                                                  node-switchbot
                                                                                                                    Preparing search index...

                                                                                                                    Class WoHumi2

                                                                                                                    Humidifier 2 Device +Uses same logic as Humidifier

                                                                                                                    +

                                                                                                                    Hierarchy (View Summary)

                                                                                                                    Index

                                                                                                                    Constructors

                                                                                                                    Accessors

                                                                                                                    • get address(): string

                                                                                                                      Returns string

                                                                                                                    • get connectionState(): string

                                                                                                                      Returns string

                                                                                                                    • get id(): string

                                                                                                                      Returns string

                                                                                                                    • get onConnectHandler(): () => Promise<void>

                                                                                                                      Returns () => Promise<void>

                                                                                                                    • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                      Parameters

                                                                                                                      • func: () => Promise<void>

                                                                                                                      Returns void

                                                                                                                    • get onDisconnectHandler(): () => Promise<void>

                                                                                                                      Returns () => Promise<void>

                                                                                                                    • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                      Parameters

                                                                                                                      • func: () => Promise<void>

                                                                                                                      Returns void

                                                                                                                    Methods

                                                                                                                    • Sends a command to the device and awaits a response.

                                                                                                                      -

                                                                                                                      Parameters

                                                                                                                      • reqBuf: Buffer

                                                                                                                        The command buffer.

                                                                                                                        -

                                                                                                                      Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                      A Promise that resolves with the response buffer.

                                                                                                                      -
                                                                                                                    • Decreases the humidifier setting.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Increases the humidifier setting.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Internal method to handle the connection process.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                      A Promise that resolves when the connection is complete.

                                                                                                                      -
                                                                                                                    • Logs a message with the specified log level.

                                                                                                                      -

                                                                                                                      Parameters

                                                                                                                      • level: string

                                                                                                                        The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                        -
                                                                                                                      • message: string

                                                                                                                        The log message to be emitted.

                                                                                                                        -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Sets the humidifier level.

                                                                                                                      -

                                                                                                                      Parameters

                                                                                                                      • level: number

                                                                                                                        The level to set (0-100).

                                                                                                                        -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Sets the humidifier to auto mode.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Sets the device name.

                                                                                                                      -

                                                                                                                      Parameters

                                                                                                                      • name: string

                                                                                                                        The new device name.

                                                                                                                        -

                                                                                                                      Returns Promise<void>

                                                                                                                      A Promise that resolves when the name is set.

                                                                                                                      -
                                                                                                                    • Sets the humidifier to manual mode.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Turns off the humidifier.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Turns on the humidifier.

                                                                                                                      -

                                                                                                                      Returns Promise<void>

                                                                                                                    • Parses the service data for WoHumi.

                                                                                                                      -

                                                                                                                      Parameters

                                                                                                                      • serviceData: Buffer

                                                                                                                        The service data buffer.

                                                                                                                        -
                                                                                                                      • emitLog: (level: string, message: string) => void

                                                                                                                        The function to emit log messages.

                                                                                                                        -

                                                                                                                      Returns Promise<null | humidifier2ServiceData>

                                                                                                                        -
                                                                                                                      • Parsed service data or null if invalid.
                                                                                                                      • -
                                                                                                                      -
                                                                                                                    +mac +name +

                                                                                                                    Methods

                                                                                                                    Constructors

                                                                                                                    • Parameters

                                                                                                                      • info: DeviceInfo
                                                                                                                      • options: {
                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                            enableFallback?: boolean;
                                                                                                                            enableRetry?: boolean;
                                                                                                                            logLevel?: number;
                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                        } = {}

                                                                                                                      Returns WoHumi2

                                                                                                                    Accessors

                                                                                                                    • get deviceType(): string

                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                      +

                                                                                                                      Returns string

                                                                                                                    • get id(): string | undefined

                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                      +

                                                                                                                      Returns string | undefined

                                                                                                                    • get mac(): string | undefined

                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                      +

                                                                                                                      Returns string | undefined

                                                                                                                    • get name(): string

                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                      +

                                                                                                                      Returns string

                                                                                                                    Methods

                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                      +

                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                      +

                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                      +

                                                                                                                      Returns Promise<CommandResult>

                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                      +

                                                                                                                      Parameters

                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                      Returns boolean

                                                                                                                    • Register a custom fallback handler

                                                                                                                      +

                                                                                                                      Parameters

                                                                                                                      • handler: FallbackHandler
                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                      Returns string

                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                      +

                                                                                                                      Parameters

                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                      Returns Promise<boolean>

                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                      +

                                                                                                                      Parameters

                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                      Returns Promise<boolean>

                                                                                                                    • Set target humidity level (1-100)

                                                                                                                      +

                                                                                                                      Parameters

                                                                                                                      • level: number

                                                                                                                      Returns Promise<boolean>

                                                                                                                    diff --git a/docs/classes/WoIOSensorTH.html b/docs/classes/WoIOSensorTH.html index 53647273..99cd24b8 100644 --- a/docs/classes/WoIOSensorTH.html +++ b/docs/classes/WoIOSensorTH.html @@ -1,53 +1,83 @@ -WoIOSensorTH | node-switchbot
                                                                                                                    node-switchbot
                                                                                                                      Preparing search index...

                                                                                                                      Class WoIOSensorTH

                                                                                                                      Class representing a WoIOSensorTH device.

                                                                                                                      -

                                                                                                                      Hierarchy (View Summary)

                                                                                                                      Index

                                                                                                                      Constructors

                                                                                                                      Accessors

                                                                                                                      address -connectionState -friendlyName +WoIOSensorTH | node-switchbot
                                                                                                                      node-switchbot
                                                                                                                        Preparing search index...

                                                                                                                        Class WoIOSensorTH

                                                                                                                        Outdoor Meter (Temperature/Humidity Sensor for outdoor use) +Uses same logic as standard Meter

                                                                                                                        +

                                                                                                                        Hierarchy (View Summary)

                                                                                                                        Index

                                                                                                                        Constructors

                                                                                                                        Accessors

                                                                                                                        • get address(): string

                                                                                                                          Returns string

                                                                                                                        • get connectionState(): string

                                                                                                                          Returns string

                                                                                                                        • get id(): string

                                                                                                                          Returns string

                                                                                                                        • get onConnectHandler(): () => Promise<void>

                                                                                                                          Returns () => Promise<void>

                                                                                                                        • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                          Parameters

                                                                                                                          • func: () => Promise<void>

                                                                                                                          Returns void

                                                                                                                        • get onDisconnectHandler(): () => Promise<void>

                                                                                                                          Returns () => Promise<void>

                                                                                                                        • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                          Parameters

                                                                                                                          • func: () => Promise<void>

                                                                                                                          Returns void

                                                                                                                        Methods

                                                                                                                        • Sends a command to the device and awaits a response.

                                                                                                                          -

                                                                                                                          Parameters

                                                                                                                          • reqBuf: Buffer

                                                                                                                            The command buffer.

                                                                                                                            -

                                                                                                                          Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                          A Promise that resolves with the response buffer.

                                                                                                                          -
                                                                                                                        • Internal method to handle the connection process.

                                                                                                                          -

                                                                                                                          Returns Promise<void>

                                                                                                                          A Promise that resolves when the connection is complete.

                                                                                                                          -
                                                                                                                        • Logs a message with the specified log level.

                                                                                                                          -

                                                                                                                          Parameters

                                                                                                                          • level: string

                                                                                                                            The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                            -
                                                                                                                          • message: string

                                                                                                                            The log message to be emitted.

                                                                                                                            -

                                                                                                                          Returns Promise<void>

                                                                                                                        • Sets the device name.

                                                                                                                          -

                                                                                                                          Parameters

                                                                                                                          • name: string

                                                                                                                            The new device name.

                                                                                                                            -

                                                                                                                          Returns Promise<void>

                                                                                                                          A Promise that resolves when the name is set.

                                                                                                                          -
                                                                                                                        • Parses the service data for WoIOSensorTH.

                                                                                                                          -

                                                                                                                          Parameters

                                                                                                                          • serviceData: Buffer

                                                                                                                            The service data buffer.

                                                                                                                            -
                                                                                                                          • manufacturerData: Buffer

                                                                                                                            The manufacturer data buffer.

                                                                                                                            -
                                                                                                                          • emitLog: (level: string, message: string) => void

                                                                                                                            The function to emit log messages.

                                                                                                                            -

                                                                                                                          Returns Promise<null | outdoorMeterServiceData>

                                                                                                                            -
                                                                                                                          • Parsed service data or null if invalid.
                                                                                                                          • -
                                                                                                                          -
                                                                                                                        +mac +name +

                                                                                                                        Methods

                                                                                                                        Constructors

                                                                                                                        • Parameters

                                                                                                                          • info: DeviceInfo
                                                                                                                          • options: {
                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                enableFallback?: boolean;
                                                                                                                                enableRetry?: boolean;
                                                                                                                                logLevel?: number;
                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                            } = {}

                                                                                                                          Returns WoIOSensorTH

                                                                                                                        Accessors

                                                                                                                        • get deviceType(): string

                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                          +

                                                                                                                          Returns string

                                                                                                                        • get id(): string | undefined

                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                          +

                                                                                                                          Returns string | undefined

                                                                                                                        • get mac(): string | undefined

                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                          +

                                                                                                                          Returns string | undefined

                                                                                                                        • get name(): string

                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                          +

                                                                                                                          Returns string

                                                                                                                        Methods

                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                          +

                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                          +

                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                          +

                                                                                                                          Returns Promise<CommandResult>

                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                          +

                                                                                                                          Parameters

                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                          Returns boolean

                                                                                                                        • Register a custom fallback handler

                                                                                                                          +

                                                                                                                          Parameters

                                                                                                                          • handler: FallbackHandler
                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                          Returns string

                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                          +

                                                                                                                          Parameters

                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                          Returns Promise<boolean>

                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                          +

                                                                                                                          Parameters

                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                          Returns Promise<boolean>

                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                          +

                                                                                                                          Parameters

                                                                                                                          • mode: string | number

                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                            +

                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                            +

                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                            +

                                                                                                                          Returns Promise<CommandResult>

                                                                                                                        diff --git a/docs/classes/WoKeypad.html b/docs/classes/WoKeypad.html index ea40f24d..173671c1 100644 --- a/docs/classes/WoKeypad.html +++ b/docs/classes/WoKeypad.html @@ -1,52 +1,83 @@ -WoKeypad | node-switchbot
                                                                                                                        node-switchbot
                                                                                                                          Preparing search index...

                                                                                                                          Class WoKeypad

                                                                                                                          Class representing a WoKeypad device.

                                                                                                                          -

                                                                                                                          Hierarchy (View Summary)

                                                                                                                          Index

                                                                                                                          Constructors

                                                                                                                          Accessors

                                                                                                                          address -connectionState -friendlyName +WoKeypad | node-switchbot
                                                                                                                          node-switchbot
                                                                                                                            Preparing search index...

                                                                                                                            Class WoKeypad

                                                                                                                            Keypad Device (Touch/Physical) +Note: Keypad is primarily for lock control, read-only for status

                                                                                                                            +

                                                                                                                            Hierarchy (View Summary)

                                                                                                                            Index

                                                                                                                            Constructors

                                                                                                                            Accessors

                                                                                                                            • get address(): string

                                                                                                                              Returns string

                                                                                                                            • get connectionState(): string

                                                                                                                              Returns string

                                                                                                                            • get id(): string

                                                                                                                              Returns string

                                                                                                                            • get onConnectHandler(): () => Promise<void>

                                                                                                                              Returns () => Promise<void>

                                                                                                                            • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                              Parameters

                                                                                                                              • func: () => Promise<void>

                                                                                                                              Returns void

                                                                                                                            • get onDisconnectHandler(): () => Promise<void>

                                                                                                                              Returns () => Promise<void>

                                                                                                                            • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                              Parameters

                                                                                                                              • func: () => Promise<void>

                                                                                                                              Returns void

                                                                                                                            Methods

                                                                                                                            • Sends a command to the device and awaits a response.

                                                                                                                              -

                                                                                                                              Parameters

                                                                                                                              • reqBuf: Buffer

                                                                                                                                The command buffer.

                                                                                                                                -

                                                                                                                              Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                              A Promise that resolves with the response buffer.

                                                                                                                              -
                                                                                                                            • Internal method to handle the connection process.

                                                                                                                              -

                                                                                                                              Returns Promise<void>

                                                                                                                              A Promise that resolves when the connection is complete.

                                                                                                                              -
                                                                                                                            • Logs a message with the specified log level.

                                                                                                                              -

                                                                                                                              Parameters

                                                                                                                              • level: string

                                                                                                                                The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                -
                                                                                                                              • message: string

                                                                                                                                The log message to be emitted.

                                                                                                                                -

                                                                                                                              Returns Promise<void>

                                                                                                                            • Sets the device name.

                                                                                                                              -

                                                                                                                              Parameters

                                                                                                                              • name: string

                                                                                                                                The new device name.

                                                                                                                                -

                                                                                                                              Returns Promise<void>

                                                                                                                              A Promise that resolves when the name is set.

                                                                                                                              -
                                                                                                                            • Parses the service data for WoKeypad.

                                                                                                                              -

                                                                                                                              Parameters

                                                                                                                              • serviceData: Buffer

                                                                                                                                The service data buffer.

                                                                                                                                -
                                                                                                                              • manufacturerData: Buffer

                                                                                                                                The manufacturer data buffer.

                                                                                                                                -
                                                                                                                              • emitLog: (level: string, message: string) => void

                                                                                                                                The function to emit log messages.

                                                                                                                                -

                                                                                                                              Returns Promise<null | keypadDetectorServiceData>

                                                                                                                                -
                                                                                                                              • Parsed service data or null if invalid.
                                                                                                                              • -
                                                                                                                              -
                                                                                                                            +mac +name +

                                                                                                                            Methods

                                                                                                                            Constructors

                                                                                                                            • Parameters

                                                                                                                              • info: DeviceInfo
                                                                                                                              • options: {
                                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                                    enableFallback?: boolean;
                                                                                                                                    enableRetry?: boolean;
                                                                                                                                    logLevel?: number;
                                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                                } = {}

                                                                                                                              Returns WoKeypad

                                                                                                                            Accessors

                                                                                                                            • get deviceType(): string

                                                                                                                              Get device type (property accessor for convenience)

                                                                                                                              +

                                                                                                                              Returns string

                                                                                                                            • get id(): string | undefined

                                                                                                                              Get device ID (property accessor for convenience)

                                                                                                                              +

                                                                                                                              Returns string | undefined

                                                                                                                            • get mac(): string | undefined

                                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                                              +

                                                                                                                              Returns string | undefined

                                                                                                                            • get name(): string

                                                                                                                              Get device name (property accessor for convenience)

                                                                                                                              +

                                                                                                                              Returns string

                                                                                                                            Methods

                                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                              +

                                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                              +

                                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                                              +

                                                                                                                              Returns Promise<CommandResult>

                                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                              +

                                                                                                                              Parameters

                                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                              Returns boolean

                                                                                                                            • Register a custom fallback handler

                                                                                                                              +

                                                                                                                              Parameters

                                                                                                                              • handler: FallbackHandler
                                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                                              Returns string

                                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                              +

                                                                                                                              Parameters

                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                              Returns Promise<boolean>

                                                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                              +

                                                                                                                              Parameters

                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                              Returns Promise<boolean>

                                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                              +

                                                                                                                              Parameters

                                                                                                                              • mode: string | number

                                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                                +

                                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                +

                                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                                +

                                                                                                                              Returns Promise<CommandResult>

                                                                                                                            diff --git a/docs/classes/WoKeypadVision.html b/docs/classes/WoKeypadVision.html new file mode 100644 index 00000000..63a7514e --- /dev/null +++ b/docs/classes/WoKeypadVision.html @@ -0,0 +1,83 @@ +WoKeypadVision | node-switchbot
                                                                                                                            node-switchbot
                                                                                                                              Preparing search index...

                                                                                                                              Class WoKeypadVision

                                                                                                                              Keypad Vision Device +Uses same logic as Keypad for lock control

                                                                                                                              +

                                                                                                                              Hierarchy (View Summary)

                                                                                                                              Index

                                                                                                                              Constructors

                                                                                                                              • Parameters

                                                                                                                                • info: DeviceInfo
                                                                                                                                • options: {
                                                                                                                                      apiClient?: OpenAPIClient;
                                                                                                                                      bleConnection?: BLEConnection;
                                                                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                      enableCircuitBreaker?: boolean;
                                                                                                                                      enableConnectionIntelligence?: boolean;
                                                                                                                                      enableFallback?: boolean;
                                                                                                                                      enableRetry?: boolean;
                                                                                                                                      logLevel?: number;
                                                                                                                                      preferredConnection?: ConnectionType;
                                                                                                                                      retryConfig?: RetryConfig;
                                                                                                                                  } = {}

                                                                                                                                Returns WoKeypadVision

                                                                                                                              Accessors

                                                                                                                              • get deviceType(): string

                                                                                                                                Get device type (property accessor for convenience)

                                                                                                                                +

                                                                                                                                Returns string

                                                                                                                              • get id(): string | undefined

                                                                                                                                Get device ID (property accessor for convenience)

                                                                                                                                +

                                                                                                                                Returns string | undefined

                                                                                                                              • get mac(): string | undefined

                                                                                                                                Get MAC address (property accessor for convenience)

                                                                                                                                +

                                                                                                                                Returns string | undefined

                                                                                                                              • get name(): string

                                                                                                                                Get device name (property accessor for convenience)

                                                                                                                                +

                                                                                                                                Returns string

                                                                                                                              Methods

                                                                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                +

                                                                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                +

                                                                                                                                Returns a CommandResult object with device info fields.

                                                                                                                                +

                                                                                                                                Returns Promise<CommandResult>

                                                                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                +

                                                                                                                                Parameters

                                                                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                Returns boolean

                                                                                                                              • Register a custom fallback handler

                                                                                                                                +

                                                                                                                                Parameters

                                                                                                                                • handler: FallbackHandler
                                                                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                                                                Returns string

                                                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                +

                                                                                                                                Parameters

                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                Returns Promise<boolean>

                                                                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                +

                                                                                                                                Parameters

                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                Returns Promise<boolean>

                                                                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                +

                                                                                                                                Parameters

                                                                                                                                • mode: string | number

                                                                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                                                                  +

                                                                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                  +

                                                                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                                                                  +

                                                                                                                                Returns Promise<CommandResult>

                                                                                                                              diff --git a/docs/classes/WoKeypadVisionPro.html b/docs/classes/WoKeypadVisionPro.html new file mode 100644 index 00000000..c57570ce --- /dev/null +++ b/docs/classes/WoKeypadVisionPro.html @@ -0,0 +1,83 @@ +WoKeypadVisionPro | node-switchbot
                                                                                                                              node-switchbot
                                                                                                                                Preparing search index...

                                                                                                                                Class WoKeypadVisionPro

                                                                                                                                SwitchBot Keypad Vision Pro device

                                                                                                                                +

                                                                                                                                Hierarchy (View Summary)

                                                                                                                                Index

                                                                                                                                Constructors

                                                                                                                                • Parameters

                                                                                                                                  • info: DeviceInfo
                                                                                                                                  • options: {
                                                                                                                                        apiClient?: OpenAPIClient;
                                                                                                                                        bleConnection?: BLEConnection;
                                                                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                        enableCircuitBreaker?: boolean;
                                                                                                                                        enableConnectionIntelligence?: boolean;
                                                                                                                                        enableFallback?: boolean;
                                                                                                                                        enableRetry?: boolean;
                                                                                                                                        logLevel?: number;
                                                                                                                                        preferredConnection?: ConnectionType;
                                                                                                                                        retryConfig?: RetryConfig;
                                                                                                                                    } = {}

                                                                                                                                  Returns WoKeypadVisionPro

                                                                                                                                Accessors

                                                                                                                                • get deviceType(): string

                                                                                                                                  Get device type (property accessor for convenience)

                                                                                                                                  +

                                                                                                                                  Returns string

                                                                                                                                • get id(): string | undefined

                                                                                                                                  Get device ID (property accessor for convenience)

                                                                                                                                  +

                                                                                                                                  Returns string | undefined

                                                                                                                                • get mac(): string | undefined

                                                                                                                                  Get MAC address (property accessor for convenience)

                                                                                                                                  +

                                                                                                                                  Returns string | undefined

                                                                                                                                • get name(): string

                                                                                                                                  Get device name (property accessor for convenience)

                                                                                                                                  +

                                                                                                                                  Returns string

                                                                                                                                Methods

                                                                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                  +

                                                                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                  +

                                                                                                                                  Returns a CommandResult object with device info fields.

                                                                                                                                  +

                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                  +

                                                                                                                                  Parameters

                                                                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                  Returns boolean

                                                                                                                                • Register a custom fallback handler

                                                                                                                                  +

                                                                                                                                  Parameters

                                                                                                                                  • handler: FallbackHandler
                                                                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                                                                  Returns string

                                                                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                  +

                                                                                                                                  Parameters

                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                  Returns Promise<boolean>

                                                                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                  +

                                                                                                                                  Parameters

                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                  Returns Promise<boolean>

                                                                                                                                • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                  +

                                                                                                                                  Parameters

                                                                                                                                  • mode: string | number

                                                                                                                                    Mode value (number or string, per-device enum recommended)

                                                                                                                                    +

                                                                                                                                    Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                    +

                                                                                                                                    Returns a CommandResult object indicating success and mode info.

                                                                                                                                    +

                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                diff --git a/docs/classes/WoLeak.html b/docs/classes/WoLeak.html index 3c39412e..1ebd1c74 100644 --- a/docs/classes/WoLeak.html +++ b/docs/classes/WoLeak.html @@ -1,53 +1,82 @@ -WoLeak | node-switchbot
                                                                                                                                node-switchbot
                                                                                                                                  Preparing search index...

                                                                                                                                  Class WoLeak

                                                                                                                                  Class representing a WoLeak device.

                                                                                                                                  -

                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                  Index

                                                                                                                                  Constructors

                                                                                                                                  Accessors

                                                                                                                                  address -connectionState -friendlyName +WoLeak | node-switchbot
                                                                                                                                  node-switchbot
                                                                                                                                    Preparing search index...

                                                                                                                                    Class WoLeak

                                                                                                                                    Water Leak Detector Device

                                                                                                                                    +

                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                    Index

                                                                                                                                    Constructors

                                                                                                                                    Accessors

                                                                                                                                    • get address(): string

                                                                                                                                      Returns string

                                                                                                                                    • get connectionState(): string

                                                                                                                                      Returns string

                                                                                                                                    • get id(): string

                                                                                                                                      Returns string

                                                                                                                                    • get onConnectHandler(): () => Promise<void>

                                                                                                                                      Returns () => Promise<void>

                                                                                                                                    • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                      Parameters

                                                                                                                                      • func: () => Promise<void>

                                                                                                                                      Returns void

                                                                                                                                    • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                      Returns () => Promise<void>

                                                                                                                                    • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                      Parameters

                                                                                                                                      • func: () => Promise<void>

                                                                                                                                      Returns void

                                                                                                                                    Methods

                                                                                                                                    • Sends a command to the device and awaits a response.

                                                                                                                                      -

                                                                                                                                      Parameters

                                                                                                                                      • reqBuf: Buffer

                                                                                                                                        The command buffer.

                                                                                                                                        -

                                                                                                                                      Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                      A Promise that resolves with the response buffer.

                                                                                                                                      -
                                                                                                                                    • Internal method to handle the connection process.

                                                                                                                                      -

                                                                                                                                      Returns Promise<void>

                                                                                                                                      A Promise that resolves when the connection is complete.

                                                                                                                                      -
                                                                                                                                    • Logs a message with the specified log level.

                                                                                                                                      -

                                                                                                                                      Parameters

                                                                                                                                      • level: string

                                                                                                                                        The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                        -
                                                                                                                                      • message: string

                                                                                                                                        The log message to be emitted.

                                                                                                                                        -

                                                                                                                                      Returns Promise<void>

                                                                                                                                    • Sets the device name.

                                                                                                                                      -

                                                                                                                                      Parameters

                                                                                                                                      • name: string

                                                                                                                                        The new device name.

                                                                                                                                        -

                                                                                                                                      Returns Promise<void>

                                                                                                                                      A Promise that resolves when the name is set.

                                                                                                                                      -
                                                                                                                                    • Parses the service data for WoLeak.

                                                                                                                                      -

                                                                                                                                      Parameters

                                                                                                                                      • serviceData: Buffer

                                                                                                                                        The service data buffer.

                                                                                                                                        -
                                                                                                                                      • manufacturerData: Buffer

                                                                                                                                        The manufacturer data buffer.

                                                                                                                                        -
                                                                                                                                      • emitLog: (level: string, message: string) => void

                                                                                                                                        The function to emit log messages.

                                                                                                                                        -

                                                                                                                                      Returns Promise<null | waterLeakDetectorServiceData>

                                                                                                                                        -
                                                                                                                                      • Parsed service data or null if invalid.
                                                                                                                                      • -
                                                                                                                                      -
                                                                                                                                    +mac +name +

                                                                                                                                    Methods

                                                                                                                                    Constructors

                                                                                                                                    • Parameters

                                                                                                                                      • info: DeviceInfo
                                                                                                                                      • options: {
                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                            enableFallback?: boolean;
                                                                                                                                            enableRetry?: boolean;
                                                                                                                                            logLevel?: number;
                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                        } = {}

                                                                                                                                      Returns WoLeak

                                                                                                                                    Accessors

                                                                                                                                    • get deviceType(): string

                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                      +

                                                                                                                                      Returns string

                                                                                                                                    • get id(): string | undefined

                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                      +

                                                                                                                                      Returns string | undefined

                                                                                                                                    • get mac(): string | undefined

                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                      +

                                                                                                                                      Returns string | undefined

                                                                                                                                    • get name(): string

                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                      +

                                                                                                                                      Returns string

                                                                                                                                    Methods

                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                      +

                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                      +

                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                      +

                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                      +

                                                                                                                                      Parameters

                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                      Returns boolean

                                                                                                                                    • Register a custom fallback handler

                                                                                                                                      +

                                                                                                                                      Parameters

                                                                                                                                      • handler: FallbackHandler
                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                      Returns string

                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                      +

                                                                                                                                      Parameters

                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                      Returns Promise<boolean>

                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                      +

                                                                                                                                      Parameters

                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                      Returns Promise<boolean>

                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                      +

                                                                                                                                      Parameters

                                                                                                                                      • mode: string | number

                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                        +

                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                        +

                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                        +

                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                    diff --git a/docs/classes/WoPanTiltCamPlus3K.html b/docs/classes/WoPanTiltCamPlus3K.html new file mode 100644 index 00000000..35d728ac --- /dev/null +++ b/docs/classes/WoPanTiltCamPlus3K.html @@ -0,0 +1,122 @@ +WoPanTiltCamPlus3K | node-switchbot
                                                                                                                                    node-switchbot
                                                                                                                                      Preparing search index...

                                                                                                                                      Class WoPanTiltCamPlus3K

                                                                                                                                      Base class for all SwitchBot devices

                                                                                                                                      + +

                                                                                                                                      This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                                                                                                      +
                                                                                                                                        +
                                                                                                                                      • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                                                                                                      • +
                                                                                                                                      • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                                                                                                      • +
                                                                                                                                      • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                                                                                                      • +
                                                                                                                                      • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                                                                                                      • +
                                                                                                                                      + +
                                                                                                                                        +
                                                                                                                                      • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                                                                                                      • +
                                                                                                                                      • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                                                                                                      • +
                                                                                                                                      • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                                                                                                      • +
                                                                                                                                      + +
                                                                                                                                      async getStatus(): Promise<DeviceStatus> {
                                                                                                                                      return this.getStatusWithFallback(
                                                                                                                                      bleData => ({ ... }), // normalize BLE data
                                                                                                                                      apiData => ({ ... }), // normalize API data
                                                                                                                                      )
                                                                                                                                      }

                                                                                                                                      async turnOn(): Promise<boolean> {
                                                                                                                                      const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                                                                                                      return result.success
                                                                                                                                      } +
                                                                                                                                      + + +
                                                                                                                                        +
                                                                                                                                      • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                                                                                                      • +
                                                                                                                                      • enableFallback: boolean (default: true)
                                                                                                                                      • +
                                                                                                                                      • enableConnectionIntelligence: boolean (default: true)
                                                                                                                                      • +
                                                                                                                                      • enableCircuitBreaker: boolean (default: true)
                                                                                                                                      • +
                                                                                                                                      • enableRetry: boolean (default: true)
                                                                                                                                      • +
                                                                                                                                      + +
                                                                                                                                        +
                                                                                                                                      • getStatusWithFallback()
                                                                                                                                      • +
                                                                                                                                      • sendCommand()
                                                                                                                                      • +
                                                                                                                                      • hasBLE(), hasAPI()
                                                                                                                                      • +
                                                                                                                                      • setPreferredConnection(), setFallbackEnabled()
                                                                                                                                      • +
                                                                                                                                      +

                                                                                                                                      This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                                                                                                      +

                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                      Index

                                                                                                                                      Constructors

                                                                                                                                      • Parameters

                                                                                                                                        • info: DeviceInfo
                                                                                                                                        • options: {
                                                                                                                                              apiClient?: OpenAPIClient;
                                                                                                                                              bleConnection?: BLEConnection;
                                                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                                                              enableFallback?: boolean;
                                                                                                                                              enableRetry?: boolean;
                                                                                                                                              logLevel?: number;
                                                                                                                                              preferredConnection?: ConnectionType;
                                                                                                                                              retryConfig?: RetryConfig;
                                                                                                                                          } = {}

                                                                                                                                        Returns WoPanTiltCamPlus3K

                                                                                                                                      Accessors

                                                                                                                                      • get deviceType(): string

                                                                                                                                        Get device type (property accessor for convenience)

                                                                                                                                        +

                                                                                                                                        Returns string

                                                                                                                                      • get id(): string | undefined

                                                                                                                                        Get device ID (property accessor for convenience)

                                                                                                                                        +

                                                                                                                                        Returns string | undefined

                                                                                                                                      • get mac(): string | undefined

                                                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                                                        +

                                                                                                                                        Returns string | undefined

                                                                                                                                      • get name(): string

                                                                                                                                        Get device name (property accessor for convenience)

                                                                                                                                        +

                                                                                                                                        Returns string

                                                                                                                                      Methods

                                                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                        +

                                                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                        +

                                                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                                                        +

                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                        +

                                                                                                                                        Parameters

                                                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                        Returns boolean

                                                                                                                                      • Register a custom fallback handler

                                                                                                                                        +

                                                                                                                                        Parameters

                                                                                                                                        • handler: FallbackHandler
                                                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                                                        Returns string

                                                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                        +

                                                                                                                                        Parameters

                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                        Returns Promise<boolean>

                                                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                        +

                                                                                                                                        Parameters

                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                        Returns Promise<boolean>

                                                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                        +

                                                                                                                                        Parameters

                                                                                                                                        • mode: string | number

                                                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                                                          +

                                                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                          +

                                                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                                                          +

                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                      diff --git a/docs/classes/WoPlugMiniJP.html b/docs/classes/WoPlugMiniJP.html index fa6f3f99..8bf1517c 100644 --- a/docs/classes/WoPlugMiniJP.html +++ b/docs/classes/WoPlugMiniJP.html @@ -1,78 +1,89 @@ -WoPlugMiniJP | node-switchbot
                                                                                                                                      node-switchbot
                                                                                                                                        Preparing search index...

                                                                                                                                        Class WoPlugMiniJP

                                                                                                                                        Class representing a WoPlugMini device.

                                                                                                                                        -

                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                        Index

                                                                                                                                        Constructors

                                                                                                                                        Accessors

                                                                                                                                        address -connectionState -friendlyName +WoPlugMiniJP | node-switchbot
                                                                                                                                        node-switchbot
                                                                                                                                          Preparing search index...

                                                                                                                                          Class WoPlugMiniJP

                                                                                                                                          Plug Mini (JP) Device +Uses same logic as US version

                                                                                                                                          +

                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                          Index

                                                                                                                                          Constructors

                                                                                                                                          Accessors

                                                                                                                                          • get address(): string

                                                                                                                                            Returns string

                                                                                                                                          • get connectionState(): string

                                                                                                                                            Returns string

                                                                                                                                          • get id(): string

                                                                                                                                            Returns string

                                                                                                                                          • get onConnectHandler(): () => Promise<void>

                                                                                                                                            Returns () => Promise<void>

                                                                                                                                          • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                            Parameters

                                                                                                                                            • func: () => Promise<void>

                                                                                                                                            Returns void

                                                                                                                                          • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                            Returns () => Promise<void>

                                                                                                                                          • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                            Parameters

                                                                                                                                            • func: () => Promise<void>

                                                                                                                                            Returns void

                                                                                                                                          Methods

                                                                                                                                          • Sends a command to the device and awaits a response.

                                                                                                                                            -

                                                                                                                                            Parameters

                                                                                                                                            • reqBuf: Buffer

                                                                                                                                              The command buffer.

                                                                                                                                              -

                                                                                                                                            Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                            A Promise that resolves with the response buffer.

                                                                                                                                            -
                                                                                                                                          • Internal method to handle the connection process.

                                                                                                                                            -

                                                                                                                                            Returns Promise<void>

                                                                                                                                            A Promise that resolves when the connection is complete.

                                                                                                                                            -
                                                                                                                                          • Logs a message with the specified log level.

                                                                                                                                            -

                                                                                                                                            Parameters

                                                                                                                                            • level: string

                                                                                                                                              The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                              -
                                                                                                                                            • message: string

                                                                                                                                              The log message to be emitted.

                                                                                                                                              -

                                                                                                                                            Returns Promise<void>

                                                                                                                                          • Operates the plug with the given bytes.

                                                                                                                                            -

                                                                                                                                            Parameters

                                                                                                                                            • bytes: number[]

                                                                                                                                              The byte array to send to the plug.

                                                                                                                                              -

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                              -
                                                                                                                                            • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          • Reads the state of the plug.

                                                                                                                                            -

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                              -
                                                                                                                                            • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          • Sets the device name.

                                                                                                                                            -

                                                                                                                                            Parameters

                                                                                                                                            • name: string

                                                                                                                                              The new device name.

                                                                                                                                              -

                                                                                                                                            Returns Promise<void>

                                                                                                                                            A Promise that resolves when the name is set.

                                                                                                                                            -
                                                                                                                                          • Toggles the state of the plug.

                                                                                                                                            -

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                              -
                                                                                                                                            • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          • Turns off the plug.

                                                                                                                                            -

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                              -
                                                                                                                                            • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          • Turns on the plug.

                                                                                                                                            -

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                              -
                                                                                                                                            • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          • Parses the service data for WoPlugMini JP.

                                                                                                                                            -

                                                                                                                                            Parameters

                                                                                                                                            • manufacturerData: Buffer

                                                                                                                                              The manufacturer data buffer.

                                                                                                                                              -
                                                                                                                                            • emitLog: (level: string, message: string) => void

                                                                                                                                              The function to emit log messages.

                                                                                                                                              -

                                                                                                                                            Returns Promise<null | plugMiniJPServiceData>

                                                                                                                                              -
                                                                                                                                            • Parsed service data or null if invalid.
                                                                                                                                            • -
                                                                                                                                            -
                                                                                                                                          +mac +name +

                                                                                                                                          Methods

                                                                                                                                          Constructors

                                                                                                                                          • Parameters

                                                                                                                                            • info: DeviceInfo
                                                                                                                                            • options: {
                                                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                                                  enableFallback?: boolean;
                                                                                                                                                  enableRetry?: boolean;
                                                                                                                                                  logLevel?: number;
                                                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                                                  retryConfig?: RetryConfig;
                                                                                                                                              } = {}

                                                                                                                                            Returns WoPlugMiniJP

                                                                                                                                          Accessors

                                                                                                                                          • get deviceType(): string

                                                                                                                                            Get device type (property accessor for convenience)

                                                                                                                                            +

                                                                                                                                            Returns string

                                                                                                                                          • get id(): string | undefined

                                                                                                                                            Get device ID (property accessor for convenience)

                                                                                                                                            +

                                                                                                                                            Returns string | undefined

                                                                                                                                          • get mac(): string | undefined

                                                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                                                            +

                                                                                                                                            Returns string | undefined

                                                                                                                                          • get name(): string

                                                                                                                                            Get device name (property accessor for convenience)

                                                                                                                                            +

                                                                                                                                            Returns string

                                                                                                                                          Methods

                                                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                            +

                                                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                            +

                                                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                                                            +

                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                            +

                                                                                                                                            Parameters

                                                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                            Returns boolean

                                                                                                                                          • Register a custom fallback handler

                                                                                                                                            +

                                                                                                                                            Parameters

                                                                                                                                            • handler: FallbackHandler
                                                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                                                            Returns string

                                                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                            +

                                                                                                                                            Parameters

                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                            +

                                                                                                                                            Parameters

                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                            Returns Promise<boolean>

                                                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                            +

                                                                                                                                            Parameters

                                                                                                                                            • mode: string | number

                                                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                                                              +

                                                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                              +

                                                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                                                              +

                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                          diff --git a/docs/classes/WoPlugMiniUS.html b/docs/classes/WoPlugMiniUS.html index 648764f4..1b82ac0c 100644 --- a/docs/classes/WoPlugMiniUS.html +++ b/docs/classes/WoPlugMiniUS.html @@ -1,78 +1,88 @@ -WoPlugMiniUS | node-switchbot
                                                                                                                                          node-switchbot
                                                                                                                                            Preparing search index...

                                                                                                                                            Class WoPlugMiniUS

                                                                                                                                            Class representing a WoPlugMini device.

                                                                                                                                            -

                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                            Index

                                                                                                                                            Constructors

                                                                                                                                            Accessors

                                                                                                                                            address -connectionState -friendlyName +WoPlugMiniUS | node-switchbot
                                                                                                                                            node-switchbot
                                                                                                                                              Preparing search index...

                                                                                                                                              Class WoPlugMiniUS

                                                                                                                                              Plug Mini (US) Device

                                                                                                                                              +

                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                              Implements

                                                                                                                                              Index

                                                                                                                                              Constructors

                                                                                                                                              Accessors

                                                                                                                                              • get address(): string

                                                                                                                                                Returns string

                                                                                                                                              • get connectionState(): string

                                                                                                                                                Returns string

                                                                                                                                              • get id(): string

                                                                                                                                                Returns string

                                                                                                                                              • get onConnectHandler(): () => Promise<void>

                                                                                                                                                Returns () => Promise<void>

                                                                                                                                              • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                Parameters

                                                                                                                                                • func: () => Promise<void>

                                                                                                                                                Returns void

                                                                                                                                              • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                Returns () => Promise<void>

                                                                                                                                              • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                Parameters

                                                                                                                                                • func: () => Promise<void>

                                                                                                                                                Returns void

                                                                                                                                              Methods

                                                                                                                                              • Sends a command to the device and awaits a response.

                                                                                                                                                -

                                                                                                                                                Parameters

                                                                                                                                                • reqBuf: Buffer

                                                                                                                                                  The command buffer.

                                                                                                                                                  -

                                                                                                                                                Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                A Promise that resolves with the response buffer.

                                                                                                                                                -
                                                                                                                                              • Internal method to handle the connection process.

                                                                                                                                                -

                                                                                                                                                Returns Promise<void>

                                                                                                                                                A Promise that resolves when the connection is complete.

                                                                                                                                                -
                                                                                                                                              • Logs a message with the specified log level.

                                                                                                                                                -

                                                                                                                                                Parameters

                                                                                                                                                • level: string

                                                                                                                                                  The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                  -
                                                                                                                                                • message: string

                                                                                                                                                  The log message to be emitted.

                                                                                                                                                  -

                                                                                                                                                Returns Promise<void>

                                                                                                                                              • Operates the plug with the given bytes.

                                                                                                                                                -

                                                                                                                                                Parameters

                                                                                                                                                • bytes: number[]

                                                                                                                                                  The byte array to send to the plug.

                                                                                                                                                  -

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                  -
                                                                                                                                                • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              • Reads the state of the plug.

                                                                                                                                                -

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                  -
                                                                                                                                                • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              • Sets the device name.

                                                                                                                                                -

                                                                                                                                                Parameters

                                                                                                                                                • name: string

                                                                                                                                                  The new device name.

                                                                                                                                                  -

                                                                                                                                                Returns Promise<void>

                                                                                                                                                A Promise that resolves when the name is set.

                                                                                                                                                -
                                                                                                                                              • Toggles the state of the plug.

                                                                                                                                                -

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                  -
                                                                                                                                                • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              • Turns off the plug.

                                                                                                                                                -

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                  -
                                                                                                                                                • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              • Turns on the plug.

                                                                                                                                                -

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                  -
                                                                                                                                                • Resolves with a boolean that tells whether the plug is ON (true) or OFF (false).
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              • Parses the service data for WoPlugMini US.

                                                                                                                                                -

                                                                                                                                                Parameters

                                                                                                                                                • manufacturerData: Buffer

                                                                                                                                                  The manufacturer data buffer.

                                                                                                                                                  -
                                                                                                                                                • emitLog: (level: string, message: string) => void

                                                                                                                                                  The function to emit log messages.

                                                                                                                                                  -

                                                                                                                                                Returns Promise<null | plugMiniUSServiceData>

                                                                                                                                                  -
                                                                                                                                                • Parsed service data or null if invalid.
                                                                                                                                                • -
                                                                                                                                                -
                                                                                                                                              +unregisterFallbackHandler +updateInfo +

                                                                                                                                              Constructors

                                                                                                                                              Accessors

                                                                                                                                              • get activeConnection(): ConnectionType | undefined

                                                                                                                                                Get active connection type (property accessor for convenience)

                                                                                                                                                +

                                                                                                                                                Returns ConnectionType | undefined

                                                                                                                                              • get deviceType(): string

                                                                                                                                                Get device type (property accessor for convenience)

                                                                                                                                                +

                                                                                                                                                Returns string

                                                                                                                                              • get id(): string | undefined

                                                                                                                                                Get device ID (property accessor for convenience)

                                                                                                                                                +

                                                                                                                                                Returns string | undefined

                                                                                                                                              • get mac(): string | undefined

                                                                                                                                                Get MAC address (property accessor for convenience)

                                                                                                                                                +

                                                                                                                                                Returns string | undefined

                                                                                                                                              • get name(): string

                                                                                                                                                Get device name (property accessor for convenience)

                                                                                                                                                +

                                                                                                                                                Returns string

                                                                                                                                              Methods

                                                                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                +

                                                                                                                                                Parameters

                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                Returns Promise<boolean>

                                                                                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                +

                                                                                                                                                Parameters

                                                                                                                                                • mode: string | number

                                                                                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                                                                                  +

                                                                                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                  +

                                                                                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                                                                                  +

                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                              diff --git a/docs/classes/WoPresence.html b/docs/classes/WoPresence.html index 95b8edb4..cef4099c 100644 --- a/docs/classes/WoPresence.html +++ b/docs/classes/WoPresence.html @@ -1,60 +1,82 @@ -WoPresence | node-switchbot
                                                                                                                                              node-switchbot
                                                                                                                                                Preparing search index...

                                                                                                                                                Class WoPresence

                                                                                                                                                Class representing a WoPresence device.

                                                                                                                                                -

                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                Index

                                                                                                                                                Constructors

                                                                                                                                                Accessors

                                                                                                                                                address -connectionState -friendlyName +WoPresence | node-switchbot
                                                                                                                                                node-switchbot
                                                                                                                                                  Preparing search index...

                                                                                                                                                  Class WoPresence

                                                                                                                                                  Motion/Presence Sensor

                                                                                                                                                  +

                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                  Index

                                                                                                                                                  Constructors

                                                                                                                                                  Accessors

                                                                                                                                                  • get address(): string

                                                                                                                                                    Returns string

                                                                                                                                                  • get connectionState(): string

                                                                                                                                                    Returns string

                                                                                                                                                  • get id(): string

                                                                                                                                                    Returns string

                                                                                                                                                  • get onConnectHandler(): () => Promise<void>

                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                  • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                    Parameters

                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                    Returns void

                                                                                                                                                  • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                  • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                    Parameters

                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                    Returns void

                                                                                                                                                  Methods

                                                                                                                                                  • Sends a command to the device and awaits a response.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • reqBuf: Buffer

                                                                                                                                                      The command buffer.

                                                                                                                                                      -

                                                                                                                                                    Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                    A Promise that resolves with the response buffer.

                                                                                                                                                    -
                                                                                                                                                  • Internal method to handle the connection process.

                                                                                                                                                    -

                                                                                                                                                    Returns Promise<void>

                                                                                                                                                    A Promise that resolves when the connection is complete.

                                                                                                                                                    -
                                                                                                                                                  • Logs a message with the specified log level.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • level: string

                                                                                                                                                      The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                      -
                                                                                                                                                    • message: string

                                                                                                                                                      The log message to be emitted.

                                                                                                                                                      -

                                                                                                                                                    Returns Promise<void>

                                                                                                                                                  • Sets the device name.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • name: string

                                                                                                                                                      The new device name.

                                                                                                                                                      -

                                                                                                                                                    Returns Promise<void>

                                                                                                                                                    A Promise that resolves when the name is set.

                                                                                                                                                    -
                                                                                                                                                  • Parses the manufacturer data for presence sensors.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • serviceData: null | Buffer<ArrayBufferLike>

                                                                                                                                                      The optional service data buffer.

                                                                                                                                                      -
                                                                                                                                                    • manufacturerData: Buffer

                                                                                                                                                      The manufacturer data buffer.

                                                                                                                                                      -
                                                                                                                                                    • emitLog: (level: string, message: string) => void

                                                                                                                                                      The function to emit log messages.

                                                                                                                                                      -

                                                                                                                                                    Returns Promise<null | presenceSensorServiceData>

                                                                                                                                                      -
                                                                                                                                                    • Parsed service data or null if invalid.
                                                                                                                                                    • -
                                                                                                                                                    -
                                                                                                                                                  • Parses the service data for WoPresence.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • serviceData: Buffer

                                                                                                                                                      The service data buffer.

                                                                                                                                                      -
                                                                                                                                                    • emitLog: (level: string, message: string) => void

                                                                                                                                                      The function to emit log messages.

                                                                                                                                                      -

                                                                                                                                                    Returns Promise<null | motionSensorServiceData>

                                                                                                                                                      -
                                                                                                                                                    • Parsed service data or null if invalid.
                                                                                                                                                    • -
                                                                                                                                                    -
                                                                                                                                                  +mac +name +

                                                                                                                                                  Methods

                                                                                                                                                  Constructors

                                                                                                                                                  • Parameters

                                                                                                                                                    • info: DeviceInfo
                                                                                                                                                    • options: {
                                                                                                                                                          apiClient?: OpenAPIClient;
                                                                                                                                                          bleConnection?: BLEConnection;
                                                                                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                                                                          enableFallback?: boolean;
                                                                                                                                                          enableRetry?: boolean;
                                                                                                                                                          logLevel?: number;
                                                                                                                                                          preferredConnection?: ConnectionType;
                                                                                                                                                          retryConfig?: RetryConfig;
                                                                                                                                                      } = {}

                                                                                                                                                    Returns WoPresence

                                                                                                                                                  Accessors

                                                                                                                                                  • get deviceType(): string

                                                                                                                                                    Get device type (property accessor for convenience)

                                                                                                                                                    +

                                                                                                                                                    Returns string

                                                                                                                                                  • get id(): string | undefined

                                                                                                                                                    Get device ID (property accessor for convenience)

                                                                                                                                                    +

                                                                                                                                                    Returns string | undefined

                                                                                                                                                  • get mac(): string | undefined

                                                                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                                                                    +

                                                                                                                                                    Returns string | undefined

                                                                                                                                                  • get name(): string

                                                                                                                                                    Get device name (property accessor for convenience)

                                                                                                                                                    +

                                                                                                                                                    Returns string

                                                                                                                                                  Methods

                                                                                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                    +

                                                                                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                    +

                                                                                                                                                    Returns a CommandResult object with device info fields.

                                                                                                                                                    +

                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                    +

                                                                                                                                                    Parameters

                                                                                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                    Returns boolean

                                                                                                                                                  • Register a custom fallback handler

                                                                                                                                                    +

                                                                                                                                                    Parameters

                                                                                                                                                    • handler: FallbackHandler
                                                                                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                    Returns string

                                                                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                    +

                                                                                                                                                    Parameters

                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                    +

                                                                                                                                                    Parameters

                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                    +

                                                                                                                                                    Parameters

                                                                                                                                                    • mode: string | number

                                                                                                                                                      Mode value (number or string, per-device enum recommended)

                                                                                                                                                      +

                                                                                                                                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                      +

                                                                                                                                                      Returns a CommandResult object indicating success and mode info.

                                                                                                                                                      +

                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                  diff --git a/docs/classes/WoRGBICBulb.html b/docs/classes/WoRGBICBulb.html new file mode 100644 index 00000000..ec9ec17d --- /dev/null +++ b/docs/classes/WoRGBICBulb.html @@ -0,0 +1,114 @@ +WoRGBICBulb | node-switchbot
                                                                                                                                                  node-switchbot
                                                                                                                                                    Preparing search index...

                                                                                                                                                    Class WoRGBICBulb

                                                                                                                                                    RGBIC Bulb Device with segmented/multi-zone color control +Supports individual LED segment control for addressable RGB+IC strips

                                                                                                                                                    +

                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                    Implements

                                                                                                                                                    • RGBICBulbCommands
                                                                                                                                                    Index

                                                                                                                                                    Constructors

                                                                                                                                                    • Parameters

                                                                                                                                                      • info: DeviceInfo
                                                                                                                                                      • options: {
                                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                            logLevel?: number;
                                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                                        } = {}

                                                                                                                                                      Returns WoRGBICBulb

                                                                                                                                                    Properties

                                                                                                                                                    EFFECTS: Record<string, number> = ...

                                                                                                                                                    Preset effect name to effect ID mapping

                                                                                                                                                    +

                                                                                                                                                    Accessors

                                                                                                                                                    • get deviceType(): string

                                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                                      +

                                                                                                                                                      Returns string

                                                                                                                                                    • get id(): string | undefined

                                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                                      +

                                                                                                                                                      Returns string | undefined

                                                                                                                                                    • get mac(): string | undefined

                                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                                      +

                                                                                                                                                      Returns string | undefined

                                                                                                                                                    • get name(): string

                                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                                      +

                                                                                                                                                      Returns string

                                                                                                                                                    Methods

                                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                      +

                                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                      +

                                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                                      +

                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                      Returns boolean

                                                                                                                                                    • Register a custom fallback handler

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • handler: FallbackHandler
                                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                      Returns string

                                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set brightness (0-100)

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • brightness: number

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set RGB color

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • red: number
                                                                                                                                                      • green: number
                                                                                                                                                      • blue: number

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • minTemp: number
                                                                                                                                                      • maxTemp: number
                                                                                                                                                      • temp: number

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set color temperature (2700-6500K)

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • temperature: number

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set preset light effect

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • effectName: string
                                                                                                                                                      • speed: number = 100

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • mode: string | number

                                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                                        +

                                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                        +

                                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                                        +

                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                    • Set color for individual LED segment

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • segmentId: number

                                                                                                                                                        Segment identifier (0-based index)

                                                                                                                                                        +
                                                                                                                                                      • red: number

                                                                                                                                                        Red value (0-255)

                                                                                                                                                        +
                                                                                                                                                      • green: number

                                                                                                                                                        Green value (0-255)

                                                                                                                                                        +
                                                                                                                                                      • blue: number

                                                                                                                                                        Blue value (0-255)

                                                                                                                                                        +

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Set effect for individual LED segment

                                                                                                                                                      +

                                                                                                                                                      Parameters

                                                                                                                                                      • segmentId: number

                                                                                                                                                        Segment identifier (0-based index)

                                                                                                                                                        +
                                                                                                                                                      • effectName: string

                                                                                                                                                        Effect name from RGBIC_EFFECTS

                                                                                                                                                        +
                                                                                                                                                      • speed: number = 50

                                                                                                                                                        Effect speed (1-100, default: 50)

                                                                                                                                                        +

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                      +

                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                    diff --git a/docs/classes/WoRGBICNeonWireRopeLight.html b/docs/classes/WoRGBICNeonWireRopeLight.html new file mode 100644 index 00000000..395f3f5b --- /dev/null +++ b/docs/classes/WoRGBICNeonWireRopeLight.html @@ -0,0 +1,126 @@ +WoRGBICNeonWireRopeLight | node-switchbot
                                                                                                                                                    node-switchbot
                                                                                                                                                      Preparing search index...

                                                                                                                                                      Class WoRGBICNeonWireRopeLight

                                                                                                                                                      Base class for all SwitchBot devices

                                                                                                                                                      + +

                                                                                                                                                      This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                                                                                                                      +
                                                                                                                                                        +
                                                                                                                                                      • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                                                                                                                      • +
                                                                                                                                                      • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                                                                                                                      • +
                                                                                                                                                      • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                                                                                                                      • +
                                                                                                                                                      • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                                                                                                                      • +
                                                                                                                                                      + +
                                                                                                                                                        +
                                                                                                                                                      • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                                                                                                                      • +
                                                                                                                                                      • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                                                                                                                      • +
                                                                                                                                                      • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                                                                                                                      • +
                                                                                                                                                      + +
                                                                                                                                                      async getStatus(): Promise<DeviceStatus> {
                                                                                                                                                      return this.getStatusWithFallback(
                                                                                                                                                      bleData => ({ ... }), // normalize BLE data
                                                                                                                                                      apiData => ({ ... }), // normalize API data
                                                                                                                                                      )
                                                                                                                                                      }

                                                                                                                                                      async turnOn(): Promise<boolean> {
                                                                                                                                                      const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                                                                                                                      return result.success
                                                                                                                                                      } +
                                                                                                                                                      + + +
                                                                                                                                                        +
                                                                                                                                                      • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                                                                                                                      • +
                                                                                                                                                      • enableFallback: boolean (default: true)
                                                                                                                                                      • +
                                                                                                                                                      • enableConnectionIntelligence: boolean (default: true)
                                                                                                                                                      • +
                                                                                                                                                      • enableCircuitBreaker: boolean (default: true)
                                                                                                                                                      • +
                                                                                                                                                      • enableRetry: boolean (default: true)
                                                                                                                                                      • +
                                                                                                                                                      + +
                                                                                                                                                        +
                                                                                                                                                      • getStatusWithFallback()
                                                                                                                                                      • +
                                                                                                                                                      • sendCommand()
                                                                                                                                                      • +
                                                                                                                                                      • hasBLE(), hasAPI()
                                                                                                                                                      • +
                                                                                                                                                      • setPreferredConnection(), setFallbackEnabled()
                                                                                                                                                      • +
                                                                                                                                                      +

                                                                                                                                                      This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                                                                                                                      +

                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                      Index

                                                                                                                                                      Constructors

                                                                                                                                                      • Parameters

                                                                                                                                                        • info: DeviceInfo
                                                                                                                                                        • options: {
                                                                                                                                                              apiClient?: OpenAPIClient;
                                                                                                                                                              bleConnection?: BLEConnection;
                                                                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                                                                              enableFallback?: boolean;
                                                                                                                                                              enableRetry?: boolean;
                                                                                                                                                              logLevel?: number;
                                                                                                                                                              preferredConnection?: ConnectionType;
                                                                                                                                                              retryConfig?: RetryConfig;
                                                                                                                                                          } = {}

                                                                                                                                                        Returns WoRGBICNeonWireRopeLight

                                                                                                                                                      Accessors

                                                                                                                                                      • get deviceType(): string

                                                                                                                                                        Get device type (property accessor for convenience)

                                                                                                                                                        +

                                                                                                                                                        Returns string

                                                                                                                                                      • get id(): string | undefined

                                                                                                                                                        Get device ID (property accessor for convenience)

                                                                                                                                                        +

                                                                                                                                                        Returns string | undefined

                                                                                                                                                      • get mac(): string | undefined

                                                                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                                                                        +

                                                                                                                                                        Returns string | undefined

                                                                                                                                                      • get name(): string

                                                                                                                                                        Get device name (property accessor for convenience)

                                                                                                                                                        +

                                                                                                                                                        Returns string

                                                                                                                                                      Methods

                                                                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                        +

                                                                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                        +

                                                                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                                                                        +

                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                        +

                                                                                                                                                        Parameters

                                                                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                        Returns boolean

                                                                                                                                                      • Register a custom fallback handler

                                                                                                                                                        +

                                                                                                                                                        Parameters

                                                                                                                                                        • handler: FallbackHandler
                                                                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                        Returns string

                                                                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                        +

                                                                                                                                                        Parameters

                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                        +

                                                                                                                                                        Parameters

                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                        +

                                                                                                                                                        Parameters

                                                                                                                                                        • mode: string | number

                                                                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                                                                          +

                                                                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                          +

                                                                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                                                                          +

                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                      diff --git a/docs/classes/WoRGBICWWFloorLamp.html b/docs/classes/WoRGBICWWFloorLamp.html new file mode 100644 index 00000000..79a080cd --- /dev/null +++ b/docs/classes/WoRGBICWWFloorLamp.html @@ -0,0 +1,114 @@ +WoRGBICWWFloorLamp | node-switchbot
                                                                                                                                                      node-switchbot
                                                                                                                                                        Preparing search index...

                                                                                                                                                        Class WoRGBICWWFloorLamp

                                                                                                                                                        RGBICWW Floor Lamp Device +Uses same logic as RGBIC Bulb with segmented control

                                                                                                                                                        +

                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                        Index

                                                                                                                                                        Constructors

                                                                                                                                                        • Parameters

                                                                                                                                                          • info: DeviceInfo
                                                                                                                                                          • options: {
                                                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                                                enableFallback?: boolean;
                                                                                                                                                                enableRetry?: boolean;
                                                                                                                                                                logLevel?: number;
                                                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                                                            } = {}

                                                                                                                                                          Returns WoRGBICWWFloorLamp

                                                                                                                                                        Properties

                                                                                                                                                        EFFECTS: Record<string, number> = ...

                                                                                                                                                        Preset effect name to effect ID mapping

                                                                                                                                                        +

                                                                                                                                                        Accessors

                                                                                                                                                        • get deviceType(): string

                                                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                                                          +

                                                                                                                                                          Returns string

                                                                                                                                                        • get id(): string | undefined

                                                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                                                          +

                                                                                                                                                          Returns string | undefined

                                                                                                                                                        • get mac(): string | undefined

                                                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                                                          +

                                                                                                                                                          Returns string | undefined

                                                                                                                                                        • get name(): string

                                                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                                                          +

                                                                                                                                                          Returns string

                                                                                                                                                        Methods

                                                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                          +

                                                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                          +

                                                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                                                          +

                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                          Returns boolean

                                                                                                                                                        • Register a custom fallback handler

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • handler: FallbackHandler
                                                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                          Returns string

                                                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Set RGB color

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • red: number
                                                                                                                                                          • green: number
                                                                                                                                                          • blue: number

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • minTemp: number
                                                                                                                                                          • maxTemp: number
                                                                                                                                                          • temp: number

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Set preset light effect

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • effectName: string
                                                                                                                                                          • speed: number = 100

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • mode: string | number

                                                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                                                            +

                                                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                            +

                                                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                                                            +

                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                        • Set color for individual LED segment

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • segmentId: number

                                                                                                                                                            Segment identifier (0-based index)

                                                                                                                                                            +
                                                                                                                                                          • red: number

                                                                                                                                                            Red value (0-255)

                                                                                                                                                            +
                                                                                                                                                          • green: number

                                                                                                                                                            Green value (0-255)

                                                                                                                                                            +
                                                                                                                                                          • blue: number

                                                                                                                                                            Blue value (0-255)

                                                                                                                                                            +

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Set effect for individual LED segment

                                                                                                                                                          +

                                                                                                                                                          Parameters

                                                                                                                                                          • segmentId: number

                                                                                                                                                            Segment identifier (0-based index)

                                                                                                                                                            +
                                                                                                                                                          • effectName: string

                                                                                                                                                            Effect name from RGBIC_EFFECTS

                                                                                                                                                            +
                                                                                                                                                          • speed: number = 50

                                                                                                                                                            Effect speed (1-100, default: 50)

                                                                                                                                                            +

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                          +

                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                        diff --git a/docs/classes/WoRGBICWWStripLight.html b/docs/classes/WoRGBICWWStripLight.html new file mode 100644 index 00000000..c2f2490c --- /dev/null +++ b/docs/classes/WoRGBICWWStripLight.html @@ -0,0 +1,114 @@ +WoRGBICWWStripLight | node-switchbot
                                                                                                                                                        node-switchbot
                                                                                                                                                          Preparing search index...

                                                                                                                                                          Class WoRGBICWWStripLight

                                                                                                                                                          RGBICWW Strip Light Device +Uses same logic as RGBIC Bulb with segmented control

                                                                                                                                                          +

                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                          Index

                                                                                                                                                          Constructors

                                                                                                                                                          • Parameters

                                                                                                                                                            • info: DeviceInfo
                                                                                                                                                            • options: {
                                                                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                                                                  enableFallback?: boolean;
                                                                                                                                                                  enableRetry?: boolean;
                                                                                                                                                                  logLevel?: number;
                                                                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                                                                  retryConfig?: RetryConfig;
                                                                                                                                                              } = {}

                                                                                                                                                            Returns WoRGBICWWStripLight

                                                                                                                                                          Properties

                                                                                                                                                          EFFECTS: Record<string, number> = ...

                                                                                                                                                          Preset effect name to effect ID mapping

                                                                                                                                                          +

                                                                                                                                                          Accessors

                                                                                                                                                          • get deviceType(): string

                                                                                                                                                            Get device type (property accessor for convenience)

                                                                                                                                                            +

                                                                                                                                                            Returns string

                                                                                                                                                          • get id(): string | undefined

                                                                                                                                                            Get device ID (property accessor for convenience)

                                                                                                                                                            +

                                                                                                                                                            Returns string | undefined

                                                                                                                                                          • get mac(): string | undefined

                                                                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                                                                            +

                                                                                                                                                            Returns string | undefined

                                                                                                                                                          • get name(): string

                                                                                                                                                            Get device name (property accessor for convenience)

                                                                                                                                                            +

                                                                                                                                                            Returns string

                                                                                                                                                          Methods

                                                                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                            +

                                                                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                            +

                                                                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                                                                            +

                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                            Returns boolean

                                                                                                                                                          • Register a custom fallback handler

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • handler: FallbackHandler
                                                                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                            Returns string

                                                                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Set RGB color

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • red: number
                                                                                                                                                            • green: number
                                                                                                                                                            • blue: number

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • minTemp: number
                                                                                                                                                            • maxTemp: number
                                                                                                                                                            • temp: number

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Set preset light effect

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • effectName: string
                                                                                                                                                            • speed: number = 100

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • mode: string | number

                                                                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                                                                              +

                                                                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                              +

                                                                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                                                                              +

                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                          • Set color for individual LED segment

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • segmentId: number

                                                                                                                                                              Segment identifier (0-based index)

                                                                                                                                                              +
                                                                                                                                                            • red: number

                                                                                                                                                              Red value (0-255)

                                                                                                                                                              +
                                                                                                                                                            • green: number

                                                                                                                                                              Green value (0-255)

                                                                                                                                                              +
                                                                                                                                                            • blue: number

                                                                                                                                                              Blue value (0-255)

                                                                                                                                                              +

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Set effect for individual LED segment

                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            • segmentId: number

                                                                                                                                                              Segment identifier (0-based index)

                                                                                                                                                              +
                                                                                                                                                            • effectName: string

                                                                                                                                                              Effect name from RGBIC_EFFECTS

                                                                                                                                                              +
                                                                                                                                                            • speed: number = 50

                                                                                                                                                              Effect speed (1-100, default: 50)

                                                                                                                                                              +

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                            +

                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                          diff --git a/docs/classes/WoRelaySwitch1.html b/docs/classes/WoRelaySwitch1.html index 8ddc4dc5..13947439 100644 --- a/docs/classes/WoRelaySwitch1.html +++ b/docs/classes/WoRelaySwitch1.html @@ -1,57 +1,93 @@ -WoRelaySwitch1 | node-switchbot
                                                                                                                                                          node-switchbot
                                                                                                                                                            Preparing search index...

                                                                                                                                                            Class WoRelaySwitch1

                                                                                                                                                            Class representing a WoRelaySwitch1 device.

                                                                                                                                                            -

                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                            Index

                                                                                                                                                            Constructors

                                                                                                                                                            Accessors

                                                                                                                                                            address -connectionState -friendlyName +WoRelaySwitch1 | node-switchbot
                                                                                                                                                            node-switchbot
                                                                                                                                                              Preparing search index...

                                                                                                                                                              Class WoRelaySwitch1

                                                                                                                                                              Relay Switch 1 Device (1-channel)

                                                                                                                                                              +

                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                              Implements

                                                                                                                                                              Index

                                                                                                                                                              Constructors

                                                                                                                                                              Accessors

                                                                                                                                                              • get address(): string

                                                                                                                                                                Returns string

                                                                                                                                                              • get connectionState(): string

                                                                                                                                                                Returns string

                                                                                                                                                              • get id(): string

                                                                                                                                                                Returns string

                                                                                                                                                              • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                Returns () => Promise<void>

                                                                                                                                                              • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                Parameters

                                                                                                                                                                • func: () => Promise<void>

                                                                                                                                                                Returns void

                                                                                                                                                              • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                Returns () => Promise<void>

                                                                                                                                                              • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                Parameters

                                                                                                                                                                • func: () => Promise<void>

                                                                                                                                                                Returns void

                                                                                                                                                              Methods

                                                                                                                                                              • Sends a command to the device and awaits a response.

                                                                                                                                                                -

                                                                                                                                                                Parameters

                                                                                                                                                                • reqBuf: Buffer

                                                                                                                                                                  The command buffer.

                                                                                                                                                                  -

                                                                                                                                                                Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                A Promise that resolves with the response buffer.

                                                                                                                                                                -
                                                                                                                                                              • Internal method to handle the connection process.

                                                                                                                                                                -

                                                                                                                                                                Returns Promise<void>

                                                                                                                                                                A Promise that resolves when the connection is complete.

                                                                                                                                                                -
                                                                                                                                                              • Logs a message with the specified log level.

                                                                                                                                                                -

                                                                                                                                                                Parameters

                                                                                                                                                                • level: string

                                                                                                                                                                  The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                  -
                                                                                                                                                                • message: string

                                                                                                                                                                  The log message to be emitted.

                                                                                                                                                                  -

                                                                                                                                                                Returns Promise<void>

                                                                                                                                                              • Sets the device name.

                                                                                                                                                                -

                                                                                                                                                                Parameters

                                                                                                                                                                • name: string

                                                                                                                                                                  The new device name.

                                                                                                                                                                  -

                                                                                                                                                                Returns Promise<void>

                                                                                                                                                                A Promise that resolves when the name is set.

                                                                                                                                                                -
                                                                                                                                                              • Turns off the bot.

                                                                                                                                                                -

                                                                                                                                                                Returns Promise<void>

                                                                                                                                                              • Turns on the bot.

                                                                                                                                                                -

                                                                                                                                                                Returns Promise<void>

                                                                                                                                                              • Parses the service data for WoRelaySwitch1.

                                                                                                                                                                -

                                                                                                                                                                Parameters

                                                                                                                                                                • serviceData: Buffer

                                                                                                                                                                  The service data buffer.

                                                                                                                                                                  -
                                                                                                                                                                • manufacturerData: Buffer

                                                                                                                                                                  The manufacturer data buffer.

                                                                                                                                                                  -
                                                                                                                                                                • emitLog: (level: string, message: string) => void

                                                                                                                                                                  The function to emit log messages.

                                                                                                                                                                  -

                                                                                                                                                                Returns Promise<null | relaySwitch1ServiceData>

                                                                                                                                                                  -
                                                                                                                                                                • Parsed service data or null if invalid.
                                                                                                                                                                • -
                                                                                                                                                                -
                                                                                                                                                              +unregisterFallbackHandler +update +updateInfo +verifyEncryptionKey +

                                                                                                                                                              Constructors

                                                                                                                                                              • Parameters

                                                                                                                                                                • info: DeviceInfo
                                                                                                                                                                • options: {
                                                                                                                                                                      apiClient?: OpenAPIClient;
                                                                                                                                                                      bleConnection?: BLEConnection;
                                                                                                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                      enableCircuitBreaker?: boolean;
                                                                                                                                                                      enableConnectionIntelligence?: boolean;
                                                                                                                                                                      enableFallback?: boolean;
                                                                                                                                                                      enableRetry?: boolean;
                                                                                                                                                                      logLevel?: number;
                                                                                                                                                                      preferredConnection?: ConnectionType;
                                                                                                                                                                      retryConfig?: RetryConfig;
                                                                                                                                                                  } = {}

                                                                                                                                                                Returns WoRelaySwitch1

                                                                                                                                                              Accessors

                                                                                                                                                              • get deviceType(): string

                                                                                                                                                                Get device type (property accessor for convenience)

                                                                                                                                                                +

                                                                                                                                                                Returns string

                                                                                                                                                              • get id(): string | undefined

                                                                                                                                                                Get device ID (property accessor for convenience)

                                                                                                                                                                +

                                                                                                                                                                Returns string | undefined

                                                                                                                                                              • get mac(): string | undefined

                                                                                                                                                                Get MAC address (property accessor for convenience)

                                                                                                                                                                +

                                                                                                                                                                Returns string | undefined

                                                                                                                                                              • get name(): string

                                                                                                                                                                Get device name (property accessor for convenience)

                                                                                                                                                                +

                                                                                                                                                                Returns string

                                                                                                                                                              Methods

                                                                                                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                +

                                                                                                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                +

                                                                                                                                                                Returns a CommandResult object with device info fields.

                                                                                                                                                                +

                                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                +

                                                                                                                                                                Parameters

                                                                                                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                Returns boolean

                                                                                                                                                              • Register a custom fallback handler

                                                                                                                                                                +

                                                                                                                                                                Parameters

                                                                                                                                                                • handler: FallbackHandler
                                                                                                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                Returns string

                                                                                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                +

                                                                                                                                                                Parameters

                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                +

                                                                                                                                                                Parameters

                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                +

                                                                                                                                                                Parameters

                                                                                                                                                                • mode: string | number

                                                                                                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                                                                                                  +

                                                                                                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                  +

                                                                                                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                  +

                                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                                              • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                                +

                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                              diff --git a/docs/classes/WoRelaySwitch1PM.html b/docs/classes/WoRelaySwitch1PM.html index edd8c803..10c82782 100644 --- a/docs/classes/WoRelaySwitch1PM.html +++ b/docs/classes/WoRelaySwitch1PM.html @@ -1,57 +1,94 @@ -WoRelaySwitch1PM | node-switchbot
                                                                                                                                                              node-switchbot
                                                                                                                                                                Preparing search index...

                                                                                                                                                                Class WoRelaySwitch1PM

                                                                                                                                                                Class representing a WoRelaySwitch1PM device.

                                                                                                                                                                -

                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                Index

                                                                                                                                                                Constructors

                                                                                                                                                                Accessors

                                                                                                                                                                address -connectionState -friendlyName +WoRelaySwitch1PM | node-switchbot
                                                                                                                                                                node-switchbot
                                                                                                                                                                  Preparing search index...

                                                                                                                                                                  Class WoRelaySwitch1PM

                                                                                                                                                                  Relay Switch 1PM Device (1-channel with power monitoring) +Uses same logic as Relay Switch 1

                                                                                                                                                                  +

                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                  Index

                                                                                                                                                                  Constructors

                                                                                                                                                                  Accessors

                                                                                                                                                                  • get address(): string

                                                                                                                                                                    Returns string

                                                                                                                                                                  • get connectionState(): string

                                                                                                                                                                    Returns string

                                                                                                                                                                  • get id(): string

                                                                                                                                                                    Returns string

                                                                                                                                                                  • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                                  • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                    Parameters

                                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                                    Returns void

                                                                                                                                                                  • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                                  • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                    Parameters

                                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                                    Returns void

                                                                                                                                                                  Methods

                                                                                                                                                                  • Sends a command to the device and awaits a response.

                                                                                                                                                                    -

                                                                                                                                                                    Parameters

                                                                                                                                                                    • reqBuf: Buffer

                                                                                                                                                                      The command buffer.

                                                                                                                                                                      -

                                                                                                                                                                    Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                    A Promise that resolves with the response buffer.

                                                                                                                                                                    -
                                                                                                                                                                  • Internal method to handle the connection process.

                                                                                                                                                                    -

                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                    A Promise that resolves when the connection is complete.

                                                                                                                                                                    -
                                                                                                                                                                  • Logs a message with the specified log level.

                                                                                                                                                                    -

                                                                                                                                                                    Parameters

                                                                                                                                                                    • level: string

                                                                                                                                                                      The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                      -
                                                                                                                                                                    • message: string

                                                                                                                                                                      The log message to be emitted.

                                                                                                                                                                      -

                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                  • Sets the device name.

                                                                                                                                                                    -

                                                                                                                                                                    Parameters

                                                                                                                                                                    • name: string

                                                                                                                                                                      The new device name.

                                                                                                                                                                      -

                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                    A Promise that resolves when the name is set.

                                                                                                                                                                    -
                                                                                                                                                                  • Turns off the bot.

                                                                                                                                                                    -

                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                  • Turns on the bot.

                                                                                                                                                                    -

                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                  • Parses the service data for WoRelaySwitch1PM.

                                                                                                                                                                    -

                                                                                                                                                                    Parameters

                                                                                                                                                                    • serviceData: Buffer

                                                                                                                                                                      The service data buffer.

                                                                                                                                                                      -
                                                                                                                                                                    • manufacturerData: Buffer

                                                                                                                                                                      The manufacturer data buffer.

                                                                                                                                                                      -
                                                                                                                                                                    • emitLog: (level: string, message: string) => void

                                                                                                                                                                      The function to emit log messages.

                                                                                                                                                                      -

                                                                                                                                                                    Returns Promise<null | relaySwitch1PMServiceData>

                                                                                                                                                                      -
                                                                                                                                                                    • Parsed service data or null if invalid.
                                                                                                                                                                    • -
                                                                                                                                                                    -
                                                                                                                                                                  +mac +name +

                                                                                                                                                                  Methods

                                                                                                                                                                  Constructors

                                                                                                                                                                  • Parameters

                                                                                                                                                                    • info: DeviceInfo
                                                                                                                                                                    • options: {
                                                                                                                                                                          apiClient?: OpenAPIClient;
                                                                                                                                                                          bleConnection?: BLEConnection;
                                                                                                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                                                                                          enableFallback?: boolean;
                                                                                                                                                                          enableRetry?: boolean;
                                                                                                                                                                          logLevel?: number;
                                                                                                                                                                          preferredConnection?: ConnectionType;
                                                                                                                                                                          retryConfig?: RetryConfig;
                                                                                                                                                                      } = {}

                                                                                                                                                                    Returns WoRelaySwitch1PM

                                                                                                                                                                  Accessors

                                                                                                                                                                  • get deviceType(): string

                                                                                                                                                                    Get device type (property accessor for convenience)

                                                                                                                                                                    +

                                                                                                                                                                    Returns string

                                                                                                                                                                  • get id(): string | undefined

                                                                                                                                                                    Get device ID (property accessor for convenience)

                                                                                                                                                                    +

                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                  • get mac(): string | undefined

                                                                                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                                                                                    +

                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                  • get name(): string

                                                                                                                                                                    Get device name (property accessor for convenience)

                                                                                                                                                                    +

                                                                                                                                                                    Returns string

                                                                                                                                                                  Methods

                                                                                                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                    +

                                                                                                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                    +

                                                                                                                                                                    Returns a CommandResult object with device info fields.

                                                                                                                                                                    +

                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                    +

                                                                                                                                                                    Parameters

                                                                                                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                    Returns boolean

                                                                                                                                                                  • Register a custom fallback handler

                                                                                                                                                                    +

                                                                                                                                                                    Parameters

                                                                                                                                                                    • handler: FallbackHandler
                                                                                                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                    Returns string

                                                                                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                    +

                                                                                                                                                                    Parameters

                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                    +

                                                                                                                                                                    Parameters

                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                    +

                                                                                                                                                                    Parameters

                                                                                                                                                                    • mode: string | number

                                                                                                                                                                      Mode value (number or string, per-device enum recommended)

                                                                                                                                                                      +

                                                                                                                                                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                      +

                                                                                                                                                                      Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                      +

                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                  diff --git a/docs/classes/WoRelaySwitch2PM.html b/docs/classes/WoRelaySwitch2PM.html new file mode 100644 index 00000000..460ebf92 --- /dev/null +++ b/docs/classes/WoRelaySwitch2PM.html @@ -0,0 +1,98 @@ +WoRelaySwitch2PM | node-switchbot
                                                                                                                                                                  node-switchbot
                                                                                                                                                                    Preparing search index...

                                                                                                                                                                    Class WoRelaySwitch2PM

                                                                                                                                                                    Relay Switch 2PM Device (2-channel with power monitoring) +Extends Relay Switch 1 with channel-specific control

                                                                                                                                                                    +

                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                    Implements

                                                                                                                                                                    • RelaySwitchChannelCommands
                                                                                                                                                                    Index

                                                                                                                                                                    Constructors

                                                                                                                                                                    • Parameters

                                                                                                                                                                      • info: DeviceInfo
                                                                                                                                                                      • options: {
                                                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                                            logLevel?: number;
                                                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                                                        } = {}

                                                                                                                                                                      Returns WoRelaySwitch2PM

                                                                                                                                                                    Accessors

                                                                                                                                                                    • get deviceType(): string

                                                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                                                      +

                                                                                                                                                                      Returns string

                                                                                                                                                                    • get id(): string | undefined

                                                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                                                      +

                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                    • get mac(): string | undefined

                                                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                                                      +

                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                    • get name(): string

                                                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                                                      +

                                                                                                                                                                      Returns string

                                                                                                                                                                    Methods

                                                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                      +

                                                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                      +

                                                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                                                      +

                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                      Returns boolean

                                                                                                                                                                    • Register a custom fallback handler

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • handler: FallbackHandler
                                                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                      Returns string

                                                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                    • Set channel 1 state

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • state: boolean

                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                    • Set channel 2 state

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • state: boolean

                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                      +

                                                                                                                                                                      Parameters

                                                                                                                                                                      • mode: string | number

                                                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                                                        +

                                                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                        +

                                                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                        +

                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                    diff --git a/docs/classes/WoRemote.html b/docs/classes/WoRemote.html index d60cda9b..cb5efcd7 100644 --- a/docs/classes/WoRemote.html +++ b/docs/classes/WoRemote.html @@ -1,52 +1,83 @@ -WoRemote | node-switchbot
                                                                                                                                                                    node-switchbot
                                                                                                                                                                      Preparing search index...

                                                                                                                                                                      Class WoRemote

                                                                                                                                                                      Class representing a WoRemote device.

                                                                                                                                                                      -

                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                      Index

                                                                                                                                                                      Constructors

                                                                                                                                                                      Accessors

                                                                                                                                                                      address -connectionState -friendlyName +WoRemote | node-switchbot
                                                                                                                                                                      node-switchbot
                                                                                                                                                                        Preparing search index...

                                                                                                                                                                        Class WoRemote

                                                                                                                                                                        Remote Device (IR remote control) +Note: Remote is read-only for battery status

                                                                                                                                                                        +

                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                        Index

                                                                                                                                                                        Constructors

                                                                                                                                                                        Accessors

                                                                                                                                                                        • get address(): string

                                                                                                                                                                          Returns string

                                                                                                                                                                        • get connectionState(): string

                                                                                                                                                                          Returns string

                                                                                                                                                                        • get id(): string

                                                                                                                                                                          Returns string

                                                                                                                                                                        • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                          Returns () => Promise<void>

                                                                                                                                                                        • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                          Parameters

                                                                                                                                                                          • func: () => Promise<void>

                                                                                                                                                                          Returns void

                                                                                                                                                                        • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                          Returns () => Promise<void>

                                                                                                                                                                        • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                          Parameters

                                                                                                                                                                          • func: () => Promise<void>

                                                                                                                                                                          Returns void

                                                                                                                                                                        Methods

                                                                                                                                                                        • Sends a command to the device and awaits a response.

                                                                                                                                                                          -

                                                                                                                                                                          Parameters

                                                                                                                                                                          • reqBuf: Buffer

                                                                                                                                                                            The command buffer.

                                                                                                                                                                            -

                                                                                                                                                                          Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                          A Promise that resolves with the response buffer.

                                                                                                                                                                          -
                                                                                                                                                                        • Internal method to handle the connection process.

                                                                                                                                                                          -

                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                          A Promise that resolves when the connection is complete.

                                                                                                                                                                          -
                                                                                                                                                                        • Logs a message with the specified log level.

                                                                                                                                                                          -

                                                                                                                                                                          Parameters

                                                                                                                                                                          • level: string

                                                                                                                                                                            The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                            -
                                                                                                                                                                          • message: string

                                                                                                                                                                            The log message to be emitted.

                                                                                                                                                                            -

                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                        • Sets the device name.

                                                                                                                                                                          -

                                                                                                                                                                          Parameters

                                                                                                                                                                          • name: string

                                                                                                                                                                            The new device name.

                                                                                                                                                                            -

                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                          A Promise that resolves when the name is set.

                                                                                                                                                                          -
                                                                                                                                                                        • Parses the service data for WoRemote.

                                                                                                                                                                          -

                                                                                                                                                                          Parameters

                                                                                                                                                                          • serviceData: Buffer

                                                                                                                                                                            The service data buffer.

                                                                                                                                                                            -
                                                                                                                                                                          • emitLog: (level: string, message: string) => void

                                                                                                                                                                            The function to emit log messages.

                                                                                                                                                                            -

                                                                                                                                                                          Returns Promise<null | remoteServiceData>

                                                                                                                                                                            -
                                                                                                                                                                          • Parsed service data or null if invalid.
                                                                                                                                                                          • -
                                                                                                                                                                          -
                                                                                                                                                                        +mac +name +

                                                                                                                                                                        Methods

                                                                                                                                                                        Constructors

                                                                                                                                                                        • Parameters

                                                                                                                                                                          • info: DeviceInfo
                                                                                                                                                                          • options: {
                                                                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                                                                enableFallback?: boolean;
                                                                                                                                                                                enableRetry?: boolean;
                                                                                                                                                                                logLevel?: number;
                                                                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                                                                            } = {}

                                                                                                                                                                          Returns WoRemote

                                                                                                                                                                        Accessors

                                                                                                                                                                        • get deviceType(): string

                                                                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                                                                          +

                                                                                                                                                                          Returns string

                                                                                                                                                                        • get id(): string | undefined

                                                                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                                                                          +

                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                        • get mac(): string | undefined

                                                                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                                                                          +

                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                        • get name(): string

                                                                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                                                                          +

                                                                                                                                                                          Returns string

                                                                                                                                                                        Methods

                                                                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                          +

                                                                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                          +

                                                                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                                                                          +

                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                          +

                                                                                                                                                                          Parameters

                                                                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                          Returns boolean

                                                                                                                                                                        • Register a custom fallback handler

                                                                                                                                                                          +

                                                                                                                                                                          Parameters

                                                                                                                                                                          • handler: FallbackHandler
                                                                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                          Returns string

                                                                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                          +

                                                                                                                                                                          Parameters

                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                          +

                                                                                                                                                                          Parameters

                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                          +

                                                                                                                                                                          Parameters

                                                                                                                                                                          • mode: string | number

                                                                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                                                                            +

                                                                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                            +

                                                                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                            +

                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                        diff --git a/docs/classes/WoRemoteWithScreen.html b/docs/classes/WoRemoteWithScreen.html new file mode 100644 index 00000000..d8b2be69 --- /dev/null +++ b/docs/classes/WoRemoteWithScreen.html @@ -0,0 +1,116 @@ +WoRemoteWithScreen | node-switchbot
                                                                                                                                                                        node-switchbot
                                                                                                                                                                          Preparing search index...

                                                                                                                                                                          Class WoRemoteWithScreen

                                                                                                                                                                          Base class for all SwitchBot devices

                                                                                                                                                                          + +

                                                                                                                                                                          This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                                                                                                                                          +
                                                                                                                                                                            +
                                                                                                                                                                          • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                                                                                                                                          • +
                                                                                                                                                                          • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                                                                                                                                          • +
                                                                                                                                                                          • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                                                                                                                                          • +
                                                                                                                                                                          • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                                                                                                                                          • +
                                                                                                                                                                          + +
                                                                                                                                                                            +
                                                                                                                                                                          • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                                                                                                                                          • +
                                                                                                                                                                          • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                                                                                                                                          • +
                                                                                                                                                                          • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                                                                                                                                          • +
                                                                                                                                                                          + +
                                                                                                                                                                          async getStatus(): Promise<DeviceStatus> {
                                                                                                                                                                          return this.getStatusWithFallback(
                                                                                                                                                                          bleData => ({ ... }), // normalize BLE data
                                                                                                                                                                          apiData => ({ ... }), // normalize API data
                                                                                                                                                                          )
                                                                                                                                                                          }

                                                                                                                                                                          async turnOn(): Promise<boolean> {
                                                                                                                                                                          const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                                                                                                                                          return result.success
                                                                                                                                                                          } +
                                                                                                                                                                          + + +
                                                                                                                                                                            +
                                                                                                                                                                          • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                                                                                                                                          • +
                                                                                                                                                                          • enableFallback: boolean (default: true)
                                                                                                                                                                          • +
                                                                                                                                                                          • enableConnectionIntelligence: boolean (default: true)
                                                                                                                                                                          • +
                                                                                                                                                                          • enableCircuitBreaker: boolean (default: true)
                                                                                                                                                                          • +
                                                                                                                                                                          • enableRetry: boolean (default: true)
                                                                                                                                                                          • +
                                                                                                                                                                          + +
                                                                                                                                                                            +
                                                                                                                                                                          • getStatusWithFallback()
                                                                                                                                                                          • +
                                                                                                                                                                          • sendCommand()
                                                                                                                                                                          • +
                                                                                                                                                                          • hasBLE(), hasAPI()
                                                                                                                                                                          • +
                                                                                                                                                                          • setPreferredConnection(), setFallbackEnabled()
                                                                                                                                                                          • +
                                                                                                                                                                          +

                                                                                                                                                                          This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                                                                                                                                          +

                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                          Index

                                                                                                                                                                          Constructors

                                                                                                                                                                          • Parameters

                                                                                                                                                                            • info: DeviceInfo
                                                                                                                                                                            • options: {
                                                                                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                                                                                  enableFallback?: boolean;
                                                                                                                                                                                  enableRetry?: boolean;
                                                                                                                                                                                  logLevel?: number;
                                                                                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                                                                                  retryConfig?: RetryConfig;
                                                                                                                                                                              } = {}

                                                                                                                                                                            Returns WoRemoteWithScreen

                                                                                                                                                                          Accessors

                                                                                                                                                                          • get deviceType(): string

                                                                                                                                                                            Get device type (property accessor for convenience)

                                                                                                                                                                            +

                                                                                                                                                                            Returns string

                                                                                                                                                                          • get id(): string | undefined

                                                                                                                                                                            Get device ID (property accessor for convenience)

                                                                                                                                                                            +

                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                          • get mac(): string | undefined

                                                                                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                                                                                            +

                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                          • get name(): string

                                                                                                                                                                            Get device name (property accessor for convenience)

                                                                                                                                                                            +

                                                                                                                                                                            Returns string

                                                                                                                                                                          Methods

                                                                                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                            +

                                                                                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                            +

                                                                                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                                                                                            +

                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                            +

                                                                                                                                                                            Parameters

                                                                                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                            Returns boolean

                                                                                                                                                                          • Register a custom fallback handler

                                                                                                                                                                            +

                                                                                                                                                                            Parameters

                                                                                                                                                                            • handler: FallbackHandler
                                                                                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                            Returns string

                                                                                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                            +

                                                                                                                                                                            Parameters

                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                            +

                                                                                                                                                                            Parameters

                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                            +

                                                                                                                                                                            Parameters

                                                                                                                                                                            • mode: string | number

                                                                                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                                                                                              +

                                                                                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                              +

                                                                                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                              +

                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                          diff --git a/docs/classes/WoRollerShade.html b/docs/classes/WoRollerShade.html new file mode 100644 index 00000000..a778b28e --- /dev/null +++ b/docs/classes/WoRollerShade.html @@ -0,0 +1,95 @@ +WoRollerShade | node-switchbot
                                                                                                                                                                          node-switchbot
                                                                                                                                                                            Preparing search index...

                                                                                                                                                                            Class WoRollerShade

                                                                                                                                                                            Roller Shade Device +Uses same logic as Curtain (motorized window covering)

                                                                                                                                                                            +

                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                            Index

                                                                                                                                                                            Constructors

                                                                                                                                                                            • Parameters

                                                                                                                                                                              • info: DeviceInfo
                                                                                                                                                                              • options: {
                                                                                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                                                                                    enableFallback?: boolean;
                                                                                                                                                                                    enableRetry?: boolean;
                                                                                                                                                                                    logLevel?: number;
                                                                                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                                                                                } = {}

                                                                                                                                                                              Returns WoRollerShade

                                                                                                                                                                            Properties

                                                                                                                                                                            _lastPosition?: number

                                                                                                                                                                            Get device status

                                                                                                                                                                            +

                                                                                                                                                                            Accessors

                                                                                                                                                                            • get deviceType(): string

                                                                                                                                                                              Get device type (property accessor for convenience)

                                                                                                                                                                              +

                                                                                                                                                                              Returns string

                                                                                                                                                                            • get id(): string | undefined

                                                                                                                                                                              Get device ID (property accessor for convenience)

                                                                                                                                                                              +

                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                            • get mac(): string | undefined

                                                                                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                                                                                              +

                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                            • get name(): string

                                                                                                                                                                              Get device name (property accessor for convenience)

                                                                                                                                                                              +

                                                                                                                                                                              Returns string

                                                                                                                                                                            Methods

                                                                                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                              +

                                                                                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                              +

                                                                                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                                                                                              +

                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                              Returns boolean

                                                                                                                                                                            • Register a custom fallback handler

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • handler: FallbackHandler
                                                                                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                              Returns string

                                                                                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3 complex operations

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                            • Send multiple commands (returns true if any succeed) +Used for Curtain 3 fallback operations

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • mode: string | number

                                                                                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                +

                                                                                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                +

                                                                                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                +

                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                            • Set curtain position (0-100%)

                                                                                                                                                                              +

                                                                                                                                                                              Parameters

                                                                                                                                                                              • position: number
                                                                                                                                                                              • speed: number = 255

                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                            diff --git a/docs/classes/WoSensorTH.html b/docs/classes/WoSensorTH.html index 0bf89667..9e11d272 100644 --- a/docs/classes/WoSensorTH.html +++ b/docs/classes/WoSensorTH.html @@ -1,46 +1,82 @@ -WoSensorTH | node-switchbot
                                                                                                                                                                            node-switchbot
                                                                                                                                                                              Preparing search index...

                                                                                                                                                                              Class WoSensorTH

                                                                                                                                                                              Class representing a WoSensorTH device.

                                                                                                                                                                              -

                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                              Index

                                                                                                                                                                              Constructors

                                                                                                                                                                              Accessors

                                                                                                                                                                              address -connectionState -friendlyName +WoSensorTH | node-switchbot
                                                                                                                                                                              node-switchbot
                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                Class WoSensorTH

                                                                                                                                                                                Meter (Temperature/Humidity Sensor)

                                                                                                                                                                                +

                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                Index

                                                                                                                                                                                Constructors

                                                                                                                                                                                Accessors

                                                                                                                                                                                • get address(): string

                                                                                                                                                                                  Returns string

                                                                                                                                                                                • get connectionState(): string

                                                                                                                                                                                  Returns string

                                                                                                                                                                                • get id(): string

                                                                                                                                                                                  Returns string

                                                                                                                                                                                • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                  Returns () => Promise<void>

                                                                                                                                                                                • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • func: () => Promise<void>

                                                                                                                                                                                  Returns void

                                                                                                                                                                                • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                  Returns () => Promise<void>

                                                                                                                                                                                • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • func: () => Promise<void>

                                                                                                                                                                                  Returns void

                                                                                                                                                                                Methods

                                                                                                                                                                                • Sends a command to the device and awaits a response.

                                                                                                                                                                                  -

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • reqBuf: Buffer

                                                                                                                                                                                    The command buffer.

                                                                                                                                                                                    -

                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                  A Promise that resolves with the response buffer.

                                                                                                                                                                                  -
                                                                                                                                                                                • Internal method to handle the connection process.

                                                                                                                                                                                  -

                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                  A Promise that resolves when the connection is complete.

                                                                                                                                                                                  -
                                                                                                                                                                                • Logs a message with the specified log level.

                                                                                                                                                                                  -

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • level: string

                                                                                                                                                                                    The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                    -
                                                                                                                                                                                  • message: string

                                                                                                                                                                                    The log message to be emitted.

                                                                                                                                                                                    -

                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                • Sets the device name.

                                                                                                                                                                                  -

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • name: string

                                                                                                                                                                                    The new device name.

                                                                                                                                                                                    -

                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                  A Promise that resolves when the name is set.

                                                                                                                                                                                  -
                                                                                                                                                                                • Parameters

                                                                                                                                                                                  • serviceData: Buffer
                                                                                                                                                                                  • emitLog: (level: string, message: string) => void

                                                                                                                                                                                  Returns Promise<null | meterServiceData>

                                                                                                                                                                                +mac +name +

                                                                                                                                                                                Methods

                                                                                                                                                                                Constructors

                                                                                                                                                                                • Parameters

                                                                                                                                                                                  • info: DeviceInfo
                                                                                                                                                                                  • options: {
                                                                                                                                                                                        apiClient?: OpenAPIClient;
                                                                                                                                                                                        bleConnection?: BLEConnection;
                                                                                                                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                        enableCircuitBreaker?: boolean;
                                                                                                                                                                                        enableConnectionIntelligence?: boolean;
                                                                                                                                                                                        enableFallback?: boolean;
                                                                                                                                                                                        enableRetry?: boolean;
                                                                                                                                                                                        logLevel?: number;
                                                                                                                                                                                        preferredConnection?: ConnectionType;
                                                                                                                                                                                        retryConfig?: RetryConfig;
                                                                                                                                                                                    } = {}

                                                                                                                                                                                  Returns WoSensorTH

                                                                                                                                                                                Accessors

                                                                                                                                                                                • get deviceType(): string

                                                                                                                                                                                  Get device type (property accessor for convenience)

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns string

                                                                                                                                                                                • get id(): string | undefined

                                                                                                                                                                                  Get device ID (property accessor for convenience)

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                • get mac(): string | undefined

                                                                                                                                                                                  Get MAC address (property accessor for convenience)

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                • get name(): string

                                                                                                                                                                                  Get device name (property accessor for convenience)

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns string

                                                                                                                                                                                Methods

                                                                                                                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                  +

                                                                                                                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns a CommandResult object with device info fields.

                                                                                                                                                                                  +

                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                  +

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                  Returns boolean

                                                                                                                                                                                • Register a custom fallback handler

                                                                                                                                                                                  +

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • handler: FallbackHandler
                                                                                                                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                  Returns string

                                                                                                                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                  +

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                  +

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                  +

                                                                                                                                                                                  Parameters

                                                                                                                                                                                  • mode: string | number

                                                                                                                                                                                    Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                    +

                                                                                                                                                                                    Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                    +

                                                                                                                                                                                    Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                    +

                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                diff --git a/docs/classes/WoSensorTHPlus.html b/docs/classes/WoSensorTHPlus.html index 609a186b..808cd3e8 100644 --- a/docs/classes/WoSensorTHPlus.html +++ b/docs/classes/WoSensorTHPlus.html @@ -1,46 +1,83 @@ -WoSensorTHPlus | node-switchbot
                                                                                                                                                                                node-switchbot
                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                  Class WoSensorTHPlus

                                                                                                                                                                                  Class representing a WoSensorTH device.

                                                                                                                                                                                  -

                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                  Index

                                                                                                                                                                                  Constructors

                                                                                                                                                                                  Accessors

                                                                                                                                                                                  address -connectionState -friendlyName +WoSensorTHPlus | node-switchbot
                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                    Class WoSensorTHPlus

                                                                                                                                                                                    Meter Plus (Temperature/Humidity Sensor with screen) +Uses same logic as standard Meter

                                                                                                                                                                                    +

                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                    Index

                                                                                                                                                                                    Constructors

                                                                                                                                                                                    Accessors

                                                                                                                                                                                    • get address(): string

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    • get connectionState(): string

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    • get id(): string

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                      Returns () => Promise<void>

                                                                                                                                                                                    • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • func: () => Promise<void>

                                                                                                                                                                                      Returns void

                                                                                                                                                                                    • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                      Returns () => Promise<void>

                                                                                                                                                                                    • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • func: () => Promise<void>

                                                                                                                                                                                      Returns void

                                                                                                                                                                                    Methods

                                                                                                                                                                                    • Sends a command to the device and awaits a response.

                                                                                                                                                                                      -

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • reqBuf: Buffer

                                                                                                                                                                                        The command buffer.

                                                                                                                                                                                        -

                                                                                                                                                                                      Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                      A Promise that resolves with the response buffer.

                                                                                                                                                                                      -
                                                                                                                                                                                    • Internal method to handle the connection process.

                                                                                                                                                                                      -

                                                                                                                                                                                      Returns Promise<void>

                                                                                                                                                                                      A Promise that resolves when the connection is complete.

                                                                                                                                                                                      -
                                                                                                                                                                                    • Logs a message with the specified log level.

                                                                                                                                                                                      -

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • level: string

                                                                                                                                                                                        The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                        -
                                                                                                                                                                                      • message: string

                                                                                                                                                                                        The log message to be emitted.

                                                                                                                                                                                        -

                                                                                                                                                                                      Returns Promise<void>

                                                                                                                                                                                    • Sets the device name.

                                                                                                                                                                                      -

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • name: string

                                                                                                                                                                                        The new device name.

                                                                                                                                                                                        -

                                                                                                                                                                                      Returns Promise<void>

                                                                                                                                                                                      A Promise that resolves when the name is set.

                                                                                                                                                                                      -
                                                                                                                                                                                    • Parameters

                                                                                                                                                                                      • serviceData: Buffer
                                                                                                                                                                                      • emitLog: (level: string, message: string) => void

                                                                                                                                                                                      Returns Promise<null | meterPlusServiceData>

                                                                                                                                                                                    +mac +name +

                                                                                                                                                                                    Methods

                                                                                                                                                                                    Constructors

                                                                                                                                                                                    • Parameters

                                                                                                                                                                                      • info: DeviceInfo
                                                                                                                                                                                      • options: {
                                                                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                                                            logLevel?: number;
                                                                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                                                                        } = {}

                                                                                                                                                                                      Returns WoSensorTHPlus

                                                                                                                                                                                    Accessors

                                                                                                                                                                                    • get deviceType(): string

                                                                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    • get id(): string | undefined

                                                                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                    • get mac(): string | undefined

                                                                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                    • get name(): string

                                                                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    Methods

                                                                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                      +

                                                                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                                                                      +

                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                      +

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                      Returns boolean

                                                                                                                                                                                    • Register a custom fallback handler

                                                                                                                                                                                      +

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • handler: FallbackHandler
                                                                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                      Returns string

                                                                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                      +

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                      +

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                      +

                                                                                                                                                                                      Parameters

                                                                                                                                                                                      • mode: string | number

                                                                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                        +

                                                                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                        +

                                                                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                        +

                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                    diff --git a/docs/classes/WoSensorTHPro.html b/docs/classes/WoSensorTHPro.html index a7929f71..319698bf 100644 --- a/docs/classes/WoSensorTHPro.html +++ b/docs/classes/WoSensorTHPro.html @@ -1,46 +1,83 @@ -WoSensorTHPro | node-switchbot
                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                      Class WoSensorTHPro

                                                                                                                                                                                      Class representing a WoSensorTH device.

                                                                                                                                                                                      -

                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                      Index

                                                                                                                                                                                      Constructors

                                                                                                                                                                                      Accessors

                                                                                                                                                                                      address -connectionState -friendlyName +WoSensorTHPro | node-switchbot
                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                        Class WoSensorTHPro

                                                                                                                                                                                        Meter Pro (Advanced Temperature/Humidity Sensor) +Uses same logic as standard Meter

                                                                                                                                                                                        +

                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                        Index

                                                                                                                                                                                        Constructors

                                                                                                                                                                                        Accessors

                                                                                                                                                                                        • get address(): string

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        • get connectionState(): string

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        • get id(): string

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                          Returns () => Promise<void>

                                                                                                                                                                                        • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • func: () => Promise<void>

                                                                                                                                                                                          Returns void

                                                                                                                                                                                        • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                          Returns () => Promise<void>

                                                                                                                                                                                        • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • func: () => Promise<void>

                                                                                                                                                                                          Returns void

                                                                                                                                                                                        Methods

                                                                                                                                                                                        • Sends a command to the device and awaits a response.

                                                                                                                                                                                          -

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • reqBuf: Buffer

                                                                                                                                                                                            The command buffer.

                                                                                                                                                                                            -

                                                                                                                                                                                          Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                          A Promise that resolves with the response buffer.

                                                                                                                                                                                          -
                                                                                                                                                                                        • Internal method to handle the connection process.

                                                                                                                                                                                          -

                                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                                          A Promise that resolves when the connection is complete.

                                                                                                                                                                                          -
                                                                                                                                                                                        • Logs a message with the specified log level.

                                                                                                                                                                                          -

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • level: string

                                                                                                                                                                                            The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                            -
                                                                                                                                                                                          • message: string

                                                                                                                                                                                            The log message to be emitted.

                                                                                                                                                                                            -

                                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                                        • Sets the device name.

                                                                                                                                                                                          -

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • name: string

                                                                                                                                                                                            The new device name.

                                                                                                                                                                                            -

                                                                                                                                                                                          Returns Promise<void>

                                                                                                                                                                                          A Promise that resolves when the name is set.

                                                                                                                                                                                          -
                                                                                                                                                                                        • Parameters

                                                                                                                                                                                          • serviceData: Buffer
                                                                                                                                                                                          • emitLog: (level: string, message: string) => void

                                                                                                                                                                                          Returns Promise<null | meterProServiceData>

                                                                                                                                                                                        +mac +name +

                                                                                                                                                                                        Methods

                                                                                                                                                                                        Constructors

                                                                                                                                                                                        • Parameters

                                                                                                                                                                                          • info: DeviceInfo
                                                                                                                                                                                          • options: {
                                                                                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                enableFallback?: boolean;
                                                                                                                                                                                                enableRetry?: boolean;
                                                                                                                                                                                                logLevel?: number;
                                                                                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                                                                                            } = {}

                                                                                                                                                                                          Returns WoSensorTHPro

                                                                                                                                                                                        Accessors

                                                                                                                                                                                        • get deviceType(): string

                                                                                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        • get id(): string | undefined

                                                                                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                        • get mac(): string | undefined

                                                                                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                        • get name(): string

                                                                                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        Methods

                                                                                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                          +

                                                                                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                                                                                          +

                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                          +

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                          Returns boolean

                                                                                                                                                                                        • Register a custom fallback handler

                                                                                                                                                                                          +

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • handler: FallbackHandler
                                                                                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                          Returns string

                                                                                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                          +

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                          +

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                          +

                                                                                                                                                                                          Parameters

                                                                                                                                                                                          • mode: string | number

                                                                                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                            +

                                                                                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                            +

                                                                                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                            +

                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                        diff --git a/docs/classes/WoSensorTHProCO2.html b/docs/classes/WoSensorTHProCO2.html index 6d637709..f83de0e3 100644 --- a/docs/classes/WoSensorTHProCO2.html +++ b/docs/classes/WoSensorTHProCO2.html @@ -1,46 +1,83 @@ -WoSensorTHProCO2 | node-switchbot
                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                          Class WoSensorTHProCO2

                                                                                                                                                                                          Class representing a WoSensorTH device.

                                                                                                                                                                                          -

                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                          Index

                                                                                                                                                                                          Constructors

                                                                                                                                                                                          Accessors

                                                                                                                                                                                          address -connectionState -friendlyName +WoSensorTHProCO2 | node-switchbot
                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                            Class WoSensorTHProCO2

                                                                                                                                                                                            Meter Pro CO2 (Temperature/Humidity/CO2 Sensor) +Use same logic as standard Meter (CO2 data available in extended status)

                                                                                                                                                                                            +

                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                            Index

                                                                                                                                                                                            Constructors

                                                                                                                                                                                            Accessors

                                                                                                                                                                                            • get address(): string

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            • get connectionState(): string

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            • get id(): string

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                              Returns () => Promise<void>

                                                                                                                                                                                            • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • func: () => Promise<void>

                                                                                                                                                                                              Returns void

                                                                                                                                                                                            • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                              Returns () => Promise<void>

                                                                                                                                                                                            • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • func: () => Promise<void>

                                                                                                                                                                                              Returns void

                                                                                                                                                                                            Methods

                                                                                                                                                                                            • Sends a command to the device and awaits a response.

                                                                                                                                                                                              -

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • reqBuf: Buffer

                                                                                                                                                                                                The command buffer.

                                                                                                                                                                                                -

                                                                                                                                                                                              Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                              A Promise that resolves with the response buffer.

                                                                                                                                                                                              -
                                                                                                                                                                                            • Internal method to handle the connection process.

                                                                                                                                                                                              -

                                                                                                                                                                                              Returns Promise<void>

                                                                                                                                                                                              A Promise that resolves when the connection is complete.

                                                                                                                                                                                              -
                                                                                                                                                                                            • Logs a message with the specified log level.

                                                                                                                                                                                              -

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • level: string

                                                                                                                                                                                                The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                                -
                                                                                                                                                                                              • message: string

                                                                                                                                                                                                The log message to be emitted.

                                                                                                                                                                                                -

                                                                                                                                                                                              Returns Promise<void>

                                                                                                                                                                                            • Sets the device name.

                                                                                                                                                                                              -

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • name: string

                                                                                                                                                                                                The new device name.

                                                                                                                                                                                                -

                                                                                                                                                                                              Returns Promise<void>

                                                                                                                                                                                              A Promise that resolves when the name is set.

                                                                                                                                                                                              -
                                                                                                                                                                                            • Parameters

                                                                                                                                                                                              • serviceData: Buffer
                                                                                                                                                                                              • manufacturerData: Buffer
                                                                                                                                                                                              • emitLog: (level: string, message: string) => void

                                                                                                                                                                                              Returns Promise<null | meterProCO2ServiceData>

                                                                                                                                                                                            +mac +name +

                                                                                                                                                                                            Methods

                                                                                                                                                                                            Constructors

                                                                                                                                                                                            • Parameters

                                                                                                                                                                                              • info: DeviceInfo
                                                                                                                                                                                              • options: {
                                                                                                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                    enableFallback?: boolean;
                                                                                                                                                                                                    enableRetry?: boolean;
                                                                                                                                                                                                    logLevel?: number;
                                                                                                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                                                                                                } = {}

                                                                                                                                                                                              Returns WoSensorTHProCO2

                                                                                                                                                                                            Accessors

                                                                                                                                                                                            • get deviceType(): string

                                                                                                                                                                                              Get device type (property accessor for convenience)

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            • get id(): string | undefined

                                                                                                                                                                                              Get device ID (property accessor for convenience)

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                            • get mac(): string | undefined

                                                                                                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                            • get name(): string

                                                                                                                                                                                              Get device name (property accessor for convenience)

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            Methods

                                                                                                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                              +

                                                                                                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                                                                                                              +

                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                              +

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                              Returns boolean

                                                                                                                                                                                            • Register a custom fallback handler

                                                                                                                                                                                              +

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • handler: FallbackHandler
                                                                                                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                              Returns string

                                                                                                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                              +

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                              +

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                              +

                                                                                                                                                                                              Parameters

                                                                                                                                                                                              • mode: string | number

                                                                                                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                +

                                                                                                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                +

                                                                                                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                +

                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                            diff --git a/docs/classes/WoSmartLock.html b/docs/classes/WoSmartLock.html index ada9ae4a..40e60c52 100644 --- a/docs/classes/WoSmartLock.html +++ b/docs/classes/WoSmartLock.html @@ -1,113 +1,91 @@ -WoSmartLock | node-switchbot
                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                              Class WoSmartLock

                                                                                                                                                                                              Class representing a WoSmartLock device.

                                                                                                                                                                                              -

                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                              Index

                                                                                                                                                                                              Constructors

                                                                                                                                                                                              Properties

                                                                                                                                                                                              Accessors

                                                                                                                                                                                              address -connectionState -friendlyName +WoSmartLock | node-switchbot
                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                Class WoSmartLock

                                                                                                                                                                                                Smart Lock Device

                                                                                                                                                                                                +

                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                Implements

                                                                                                                                                                                                Index

                                                                                                                                                                                                Constructors

                                                                                                                                                                                                Properties

                                                                                                                                                                                                encryption_key: null | Buffer<ArrayBufferLike> = null
                                                                                                                                                                                                iv: null | Buffer<ArrayBufferLike> = null
                                                                                                                                                                                                key_id: string = ''
                                                                                                                                                                                                Result: { ERROR: number; SUCCESS: number; SUCCESS_LOW_BATTERY: number } = ...

                                                                                                                                                                                                Accessors

                                                                                                                                                                                                • get address(): string

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • get connectionState(): string

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • get id(): string

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                                  Returns () => Promise<void>

                                                                                                                                                                                                • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • func: () => Promise<void>

                                                                                                                                                                                                  Returns void

                                                                                                                                                                                                • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                                  Returns () => Promise<void>

                                                                                                                                                                                                • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • func: () => Promise<void>

                                                                                                                                                                                                  Returns void

                                                                                                                                                                                                Methods

                                                                                                                                                                                                • Sends a command to the device and awaits a response.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • reqBuf: Buffer

                                                                                                                                                                                                    The command buffer.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                  A Promise that resolves with the response buffer.

                                                                                                                                                                                                  -
                                                                                                                                                                                                • Decrypts a buffer using AES-128-CTR.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • data: Buffer

                                                                                                                                                                                                    The data to decrypt.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The decrypted data.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Encrypts a string using AES-128-CTR.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • str: string

                                                                                                                                                                                                    The string to encrypt.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<string>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The encrypted string in hex format.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Sends an encrypted command to the device.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • key: string

                                                                                                                                                                                                    The command key.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The response buffer.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Retrieves the IV from the device.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The IV buffer.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Gets general state info from the Smart Lock.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<null | object>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The state object or null if an error occurred.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Internal method to handle the connection process.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                                  A Promise that resolves when the connection is complete.

                                                                                                                                                                                                  -
                                                                                                                                                                                                • Locks the Smart Lock.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<number>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The result of the lock operation.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Logs a message with the specified log level.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • level: string

                                                                                                                                                                                                    The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • message: string

                                                                                                                                                                                                    The log message to be emitted.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                                • Operates the lock with the given command.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • key: string

                                                                                                                                                                                                    The command key.

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • Optionalencrypt: boolean = true

                                                                                                                                                                                                    Whether to encrypt the command.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The response buffer.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Sets the device name.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • name: string

                                                                                                                                                                                                    The new device name.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                                  A Promise that resolves when the name is set.

                                                                                                                                                                                                  -
                                                                                                                                                                                                • Initializes the encryption key info for valid lock communication.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • keyId: string

                                                                                                                                                                                                    The key ID.

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • encryptionKey: string

                                                                                                                                                                                                    The encryption key.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<void>

                                                                                                                                                                                                • Unlocks the Smart Lock.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<number>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The result of the unlock operation.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Unlocks the Smart Lock without unlatching the door.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Returns Promise<number>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • The result of the unlock operation.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Parameters

                                                                                                                                                                                                  • code: number

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • Parses the service data from the SwitchBot Strip Light.

                                                                                                                                                                                                  -

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • serviceData: Buffer

                                                                                                                                                                                                    The service data buffer.

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • manufacturerData: Buffer

                                                                                                                                                                                                    The manufacturer data buffer.

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • emitLog: (level: string, message: string) => void

                                                                                                                                                                                                    The function to emit log messages.

                                                                                                                                                                                                    -

                                                                                                                                                                                                  Returns Promise<null | lockServiceData>

                                                                                                                                                                                                    -
                                                                                                                                                                                                  • Parsed service data or null if invalid.
                                                                                                                                                                                                  • -
                                                                                                                                                                                                  -
                                                                                                                                                                                                • Parameters

                                                                                                                                                                                                  • res: Buffer

                                                                                                                                                                                                  Returns Promise<number>

                                                                                                                                                                                                +unregisterFallbackHandler +update +updateInfo +

                                                                                                                                                                                                Constructors

                                                                                                                                                                                                • Parameters

                                                                                                                                                                                                  • info: DeviceInfo
                                                                                                                                                                                                  • options: {
                                                                                                                                                                                                        apiClient?: OpenAPIClient;
                                                                                                                                                                                                        bleConnection?: BLEConnection;
                                                                                                                                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                        enableCircuitBreaker?: boolean;
                                                                                                                                                                                                        enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                        enableFallback?: boolean;
                                                                                                                                                                                                        enableRetry?: boolean;
                                                                                                                                                                                                        logLevel?: number;
                                                                                                                                                                                                        preferredConnection?: ConnectionType;
                                                                                                                                                                                                        retryConfig?: RetryConfig;
                                                                                                                                                                                                    } = {}

                                                                                                                                                                                                  Returns WoSmartLock

                                                                                                                                                                                                Accessors

                                                                                                                                                                                                • get deviceType(): string

                                                                                                                                                                                                  Get device type (property accessor for convenience)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • get id(): string | undefined

                                                                                                                                                                                                  Get device ID (property accessor for convenience)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                                • get mac(): string | undefined

                                                                                                                                                                                                  Get MAC address (property accessor for convenience)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                                • get name(): string

                                                                                                                                                                                                  Get device name (property accessor for convenience)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                Methods

                                                                                                                                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns a CommandResult object with device info fields.

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                  Returns boolean

                                                                                                                                                                                                • Register a custom fallback handler

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • handler: FallbackHandler
                                                                                                                                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                  • mode: string | number

                                                                                                                                                                                                    Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                    +

                                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                                diff --git a/docs/classes/WoSmartLockLite.html b/docs/classes/WoSmartLockLite.html new file mode 100644 index 00000000..b680ffc9 --- /dev/null +++ b/docs/classes/WoSmartLockLite.html @@ -0,0 +1,91 @@ +WoSmartLockLite | node-switchbot
                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                  Class WoSmartLockLite

                                                                                                                                                                                                  Smart Lock Lite Device

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                  Index

                                                                                                                                                                                                  Constructors

                                                                                                                                                                                                  • Parameters

                                                                                                                                                                                                    • info: DeviceInfo
                                                                                                                                                                                                    • options: {
                                                                                                                                                                                                          apiClient?: OpenAPIClient;
                                                                                                                                                                                                          bleConnection?: BLEConnection;
                                                                                                                                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                          enableFallback?: boolean;
                                                                                                                                                                                                          enableRetry?: boolean;
                                                                                                                                                                                                          logLevel?: number;
                                                                                                                                                                                                          preferredConnection?: ConnectionType;
                                                                                                                                                                                                          retryConfig?: RetryConfig;
                                                                                                                                                                                                      } = {}

                                                                                                                                                                                                    Returns WoSmartLockLite

                                                                                                                                                                                                  Accessors

                                                                                                                                                                                                  • get deviceType(): string

                                                                                                                                                                                                    Get device type (property accessor for convenience)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                  • get id(): string | undefined

                                                                                                                                                                                                    Get device ID (property accessor for convenience)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                  • get mac(): string | undefined

                                                                                                                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                  • get name(): string

                                                                                                                                                                                                    Get device name (property accessor for convenience)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                  Methods

                                                                                                                                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns a CommandResult object with device info fields.

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                    Returns boolean

                                                                                                                                                                                                  • Register a custom fallback handler

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                    • handler: FallbackHandler
                                                                                                                                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                    • mode: string | number

                                                                                                                                                                                                      Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                      +

                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                  diff --git a/docs/classes/WoSmartLockPro.html b/docs/classes/WoSmartLockPro.html index 3c3a9189..e8cbc5df 100644 --- a/docs/classes/WoSmartLockPro.html +++ b/docs/classes/WoSmartLockPro.html @@ -1,113 +1,95 @@ -WoSmartLockPro | node-switchbot
                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                    Class WoSmartLockPro

                                                                                                                                                                                                    Class representing a WoSmartLockPro device.

                                                                                                                                                                                                    -

                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                    Index

                                                                                                                                                                                                    Constructors

                                                                                                                                                                                                    Properties

                                                                                                                                                                                                    Accessors

                                                                                                                                                                                                    address -connectionState -friendlyName +WoSmartLockPro | node-switchbot
                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                      Class WoSmartLockPro

                                                                                                                                                                                                      Smart Lock Pro Device (with unlatch support)

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                      Implements

                                                                                                                                                                                                      Index

                                                                                                                                                                                                      Constructors

                                                                                                                                                                                                      Properties

                                                                                                                                                                                                      encryption_key: null | Buffer<ArrayBufferLike> = null
                                                                                                                                                                                                      iv: null | Buffer<ArrayBufferLike> = null
                                                                                                                                                                                                      key_id: string = ''
                                                                                                                                                                                                      Result: { ERROR: number; SUCCESS: number; SUCCESS_LOW_BATTERY: number } = ...

                                                                                                                                                                                                      Accessors

                                                                                                                                                                                                      • get address(): string

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • get connectionState(): string

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • get id(): string

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                                        Returns () => Promise<void>

                                                                                                                                                                                                      • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • func: () => Promise<void>

                                                                                                                                                                                                        Returns void

                                                                                                                                                                                                      • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                                        Returns () => Promise<void>

                                                                                                                                                                                                      • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • func: () => Promise<void>

                                                                                                                                                                                                        Returns void

                                                                                                                                                                                                      Methods

                                                                                                                                                                                                      • Sends a command to the device and awaits a response.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • reqBuf: Buffer

                                                                                                                                                                                                          The command buffer.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                        A Promise that resolves with the response buffer.

                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Decrypts a buffer using AES-128-CTR.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • data: Buffer

                                                                                                                                                                                                          The data to decrypt.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The decrypted data.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Encrypts a string using AES-128-CTR.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • str: string

                                                                                                                                                                                                          The string to encrypt.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<string>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The encrypted string in hex format.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Sends an encrypted command to the device.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • key: string

                                                                                                                                                                                                          The command key.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The response buffer.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Retrieves the IV from the device.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The IV buffer.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Gets general state info from the Smart Lock.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<null | object>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The state object or null if an error occurred.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Internal method to handle the connection process.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<void>

                                                                                                                                                                                                        A Promise that resolves when the connection is complete.

                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Locks the Smart Lock.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<number>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The result of the lock operation.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Logs a message with the specified log level.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • level: string

                                                                                                                                                                                                          The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • message: string

                                                                                                                                                                                                          The log message to be emitted.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<void>

                                                                                                                                                                                                      • Operates the lock with the given command.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • key: string

                                                                                                                                                                                                          The command key.

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • Optionalencrypt: boolean = true

                                                                                                                                                                                                          Whether to encrypt the command.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The response buffer.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Sets the device name.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • name: string

                                                                                                                                                                                                          The new device name.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<void>

                                                                                                                                                                                                        A Promise that resolves when the name is set.

                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Initializes the encryption key info for valid lock communication.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • keyId: string

                                                                                                                                                                                                          The key ID.

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • encryptionKey: string

                                                                                                                                                                                                          The encryption key.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<void>

                                                                                                                                                                                                      • Unlocks the Smart Lock.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<number>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The result of the unlock operation.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Unlocks the Smart Lock without unlatching the door.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Returns Promise<number>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • The result of the unlock operation.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Parameters

                                                                                                                                                                                                        • code: number

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • Parses the service data from the SwitchBot Strip Light.

                                                                                                                                                                                                        -

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • serviceData: Buffer

                                                                                                                                                                                                          The service data buffer.

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • manufacturerData: Buffer

                                                                                                                                                                                                          The manufacturer data buffer.

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • emitLog: (level: string, message: string) => void

                                                                                                                                                                                                          The function to emit log messages.

                                                                                                                                                                                                          -

                                                                                                                                                                                                        Returns Promise<null | lockProServiceData>

                                                                                                                                                                                                          -
                                                                                                                                                                                                        • Parsed service data or null if invalid.
                                                                                                                                                                                                        • -
                                                                                                                                                                                                        -
                                                                                                                                                                                                      • Parameters

                                                                                                                                                                                                        • res: Buffer

                                                                                                                                                                                                        Returns Promise<number>

                                                                                                                                                                                                      +unlockWithoutUnlatch +unregisterFallbackHandler +update +updateInfo +

                                                                                                                                                                                                      Constructors

                                                                                                                                                                                                      • Parameters

                                                                                                                                                                                                        • info: DeviceInfo
                                                                                                                                                                                                        • options: {
                                                                                                                                                                                                              apiClient?: OpenAPIClient;
                                                                                                                                                                                                              bleConnection?: BLEConnection;
                                                                                                                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                              enableFallback?: boolean;
                                                                                                                                                                                                              enableRetry?: boolean;
                                                                                                                                                                                                              logLevel?: number;
                                                                                                                                                                                                              preferredConnection?: ConnectionType;
                                                                                                                                                                                                              retryConfig?: RetryConfig;
                                                                                                                                                                                                          } = {}

                                                                                                                                                                                                        Returns WoSmartLockPro

                                                                                                                                                                                                      Accessors

                                                                                                                                                                                                      • get deviceType(): string

                                                                                                                                                                                                        Get device type (property accessor for convenience)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • get id(): string | undefined

                                                                                                                                                                                                        Get device ID (property accessor for convenience)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                      • get mac(): string | undefined

                                                                                                                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                      • get name(): string

                                                                                                                                                                                                        Get device name (property accessor for convenience)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      Methods

                                                                                                                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                        Returns boolean

                                                                                                                                                                                                      • Register a custom fallback handler

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • handler: FallbackHandler
                                                                                                                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                        • mode: string | number

                                                                                                                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                          +

                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                      diff --git a/docs/classes/WoSmartLockProWiFi.html b/docs/classes/WoSmartLockProWiFi.html new file mode 100644 index 00000000..a08e35e5 --- /dev/null +++ b/docs/classes/WoSmartLockProWiFi.html @@ -0,0 +1,95 @@ +WoSmartLockProWiFi | node-switchbot
                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                        Class WoSmartLockProWiFi

                                                                                                                                                                                                        Smart Lock Pro WiFi Device (with WiFi connectivity and unlatch support)

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                        Index

                                                                                                                                                                                                        Constructors

                                                                                                                                                                                                        • Parameters

                                                                                                                                                                                                          • info: DeviceInfo
                                                                                                                                                                                                          • options: {
                                                                                                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                enableFallback?: boolean;
                                                                                                                                                                                                                enableRetry?: boolean;
                                                                                                                                                                                                                logLevel?: number;
                                                                                                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                                                                                                            } = {}

                                                                                                                                                                                                          Returns WoSmartLockProWiFi

                                                                                                                                                                                                        Accessors

                                                                                                                                                                                                        • get deviceType(): string

                                                                                                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                        • get id(): string | undefined

                                                                                                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                                        • get mac(): string | undefined

                                                                                                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                                        • get name(): string

                                                                                                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                        Methods

                                                                                                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                          Returns boolean

                                                                                                                                                                                                        • Register a custom fallback handler

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                          • handler: FallbackHandler
                                                                                                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                          • mode: string | number

                                                                                                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                            +

                                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                                        diff --git a/docs/classes/WoSmartLockVision.html b/docs/classes/WoSmartLockVision.html new file mode 100644 index 00000000..b30950ab --- /dev/null +++ b/docs/classes/WoSmartLockVision.html @@ -0,0 +1,91 @@ +WoSmartLockVision | node-switchbot
                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                          Class WoSmartLockVision

                                                                                                                                                                                                          Smart Lock Vision Device (with camera)

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                          Index

                                                                                                                                                                                                          Constructors

                                                                                                                                                                                                          • Parameters

                                                                                                                                                                                                            • info: DeviceInfo
                                                                                                                                                                                                            • options: {
                                                                                                                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                  enableFallback?: boolean;
                                                                                                                                                                                                                  enableRetry?: boolean;
                                                                                                                                                                                                                  logLevel?: number;
                                                                                                                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                                                                                                                  retryConfig?: RetryConfig;
                                                                                                                                                                                                              } = {}

                                                                                                                                                                                                            Returns WoSmartLockVision

                                                                                                                                                                                                          Accessors

                                                                                                                                                                                                          • get deviceType(): string

                                                                                                                                                                                                            Get device type (property accessor for convenience)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                          • get id(): string | undefined

                                                                                                                                                                                                            Get device ID (property accessor for convenience)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                                                          • get mac(): string | undefined

                                                                                                                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                                                          • get name(): string

                                                                                                                                                                                                            Get device name (property accessor for convenience)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                          Methods

                                                                                                                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                            Returns boolean

                                                                                                                                                                                                          • Register a custom fallback handler

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                            • handler: FallbackHandler
                                                                                                                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                            • mode: string | number

                                                                                                                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                              +

                                                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                                                          diff --git a/docs/classes/WoSmartLockVisionPro.html b/docs/classes/WoSmartLockVisionPro.html new file mode 100644 index 00000000..7f146a88 --- /dev/null +++ b/docs/classes/WoSmartLockVisionPro.html @@ -0,0 +1,95 @@ +WoSmartLockVisionPro | node-switchbot
                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                            Class WoSmartLockVisionPro

                                                                                                                                                                                                            Smart Lock Vision Pro Device (with camera and unlatch support)

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                            Index

                                                                                                                                                                                                            Constructors

                                                                                                                                                                                                            • Parameters

                                                                                                                                                                                                              • info: DeviceInfo
                                                                                                                                                                                                              • options: {
                                                                                                                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                    enableFallback?: boolean;
                                                                                                                                                                                                                    enableRetry?: boolean;
                                                                                                                                                                                                                    logLevel?: number;
                                                                                                                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                                                                                                                } = {}

                                                                                                                                                                                                              Returns WoSmartLockVisionPro

                                                                                                                                                                                                            Accessors

                                                                                                                                                                                                            • get deviceType(): string

                                                                                                                                                                                                              Get device type (property accessor for convenience)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                            • get id(): string | undefined

                                                                                                                                                                                                              Get device ID (property accessor for convenience)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                                            • get mac(): string | undefined

                                                                                                                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                                            • get name(): string

                                                                                                                                                                                                              Get device name (property accessor for convenience)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                            Methods

                                                                                                                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                              Returns boolean

                                                                                                                                                                                                            • Register a custom fallback handler

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                              • handler: FallbackHandler
                                                                                                                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                              • mode: string | number

                                                                                                                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                +

                                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                                            diff --git a/docs/classes/WoSmartThermostatRadiator.html b/docs/classes/WoSmartThermostatRadiator.html new file mode 100644 index 00000000..76908616 --- /dev/null +++ b/docs/classes/WoSmartThermostatRadiator.html @@ -0,0 +1,89 @@ +WoSmartThermostatRadiator | node-switchbot
                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                              Class WoSmartThermostatRadiator

                                                                                                                                                                                                              Smart Thermostat Radiator Device +Reuses climate control behavior for power, mode, and speed-level style control.

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                                              Index

                                                                                                                                                                                                              Constructors

                                                                                                                                                                                                              • Parameters

                                                                                                                                                                                                                • info: DeviceInfo
                                                                                                                                                                                                                • options: {
                                                                                                                                                                                                                      apiClient?: OpenAPIClient;
                                                                                                                                                                                                                      bleConnection?: BLEConnection;
                                                                                                                                                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                      enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                      enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                      enableFallback?: boolean;
                                                                                                                                                                                                                      enableRetry?: boolean;
                                                                                                                                                                                                                      logLevel?: number;
                                                                                                                                                                                                                      preferredConnection?: ConnectionType;
                                                                                                                                                                                                                      retryConfig?: RetryConfig;
                                                                                                                                                                                                                  } = {}

                                                                                                                                                                                                                Returns WoSmartThermostatRadiator

                                                                                                                                                                                                              Accessors

                                                                                                                                                                                                              • get deviceType(): string

                                                                                                                                                                                                                Get device type (property accessor for convenience)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                              • get id(): string | undefined

                                                                                                                                                                                                                Get device ID (property accessor for convenience)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns string | undefined

                                                                                                                                                                                                              • get mac(): string | undefined

                                                                                                                                                                                                                Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns string | undefined

                                                                                                                                                                                                              • get name(): string

                                                                                                                                                                                                                Get device name (property accessor for convenience)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                              Methods

                                                                                                                                                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                Returns boolean

                                                                                                                                                                                                              • Register a custom fallback handler

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                • handler: FallbackHandler
                                                                                                                                                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                              • Set preset mode (level_1, level_2, level_3, auto, sleep, pet)

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                • mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet"

                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                              diff --git a/docs/classes/WoStrip.html b/docs/classes/WoStrip.html index c40c68f9..5df1e3c1 100644 --- a/docs/classes/WoStrip.html +++ b/docs/classes/WoStrip.html @@ -1,94 +1,103 @@ -WoStrip | node-switchbot
                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                Class WoStrip

                                                                                                                                                                                                                Class representing a WoStrip device.

                                                                                                                                                                                                                -

                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                Index

                                                                                                                                                                                                                Constructors

                                                                                                                                                                                                                Accessors

                                                                                                                                                                                                                address -connectionState -friendlyName +WoStrip | node-switchbot
                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                  Class WoStrip

                                                                                                                                                                                                                  Strip Light Device +Uses same logic as Color Bulb

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                  Constructors

                                                                                                                                                                                                                  Accessors

                                                                                                                                                                                                                  • get address(): string

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  • get connectionState(): string

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  • get id(): string

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  • get onConnectHandler(): () => Promise<void>

                                                                                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                                                                                  • set onConnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                                                                                    Returns void

                                                                                                                                                                                                                  • get onDisconnectHandler(): () => Promise<void>

                                                                                                                                                                                                                    Returns () => Promise<void>

                                                                                                                                                                                                                  • set onDisconnectHandler(func: () => Promise<void>): void

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • func: () => Promise<void>

                                                                                                                                                                                                                    Returns void

                                                                                                                                                                                                                  Methods

                                                                                                                                                                                                                  • Sends a command to the device and awaits a response.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • reqBuf: Buffer

                                                                                                                                                                                                                      The command buffer.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<Buffer<ArrayBufferLike>>

                                                                                                                                                                                                                    A Promise that resolves with the response buffer.

                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Internal method to handle the connection process.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                                                                    A Promise that resolves when the connection is complete.

                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Logs a message with the specified log level.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • level: string

                                                                                                                                                                                                                      The severity level of the log (e.g., 'info', 'warn', 'error').

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • message: string

                                                                                                                                                                                                                      The log message to be emitted.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                                                                  • Operates the strip light with the given byte array.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • bytes: number[]

                                                                                                                                                                                                                      The byte array to send.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the operation was successful.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Reads the state of the strip light.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the strip light is ON, false otherwise.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Sets the brightness of the strip light.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • brightness: number

                                                                                                                                                                                                                      The brightness percentage (0-100).

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the operation was successful.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Sets the device name.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • name: string

                                                                                                                                                                                                                      The new device name.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<void>

                                                                                                                                                                                                                    A Promise that resolves when the name is set.

                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Sets the RGB values of the strip light.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • brightness: number

                                                                                                                                                                                                                      The brightness percentage (0-100).

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • red: number

                                                                                                                                                                                                                      The red value (0-255).

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • green: number

                                                                                                                                                                                                                      The green value (0-255).

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • blue: number

                                                                                                                                                                                                                      The blue value (0-255).

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the operation was successful.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Sets the state of the strip light.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • reqByteArray: number[]

                                                                                                                                                                                                                      The request byte array.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the operation was successful.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Turns the strip light off.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the strip light is OFF.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Turns the strip light on.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Resolves with true if the strip light is ON.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  • Parses the service data from the SwitchBot Strip Light.

                                                                                                                                                                                                                    -

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • serviceData: Buffer

                                                                                                                                                                                                                      The service data buffer.

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • emitLog: (level: string, message: string) => void

                                                                                                                                                                                                                      The function to emit log messages.

                                                                                                                                                                                                                      -

                                                                                                                                                                                                                    Returns Promise<null | stripLightServiceData>

                                                                                                                                                                                                                      -
                                                                                                                                                                                                                    • Parsed service data or null if invalid.
                                                                                                                                                                                                                    • -
                                                                                                                                                                                                                    -
                                                                                                                                                                                                                  +mac +name +

                                                                                                                                                                                                                  Methods

                                                                                                                                                                                                                  Constructors

                                                                                                                                                                                                                  • Parameters

                                                                                                                                                                                                                    • info: DeviceInfo
                                                                                                                                                                                                                    • options: {
                                                                                                                                                                                                                          apiClient?: OpenAPIClient;
                                                                                                                                                                                                                          bleConnection?: BLEConnection;
                                                                                                                                                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                          enableFallback?: boolean;
                                                                                                                                                                                                                          enableRetry?: boolean;
                                                                                                                                                                                                                          logLevel?: number;
                                                                                                                                                                                                                          preferredConnection?: ConnectionType;
                                                                                                                                                                                                                          retryConfig?: RetryConfig;
                                                                                                                                                                                                                      } = {}

                                                                                                                                                                                                                    Returns WoStrip

                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                  EFFECTS: Record<string, number> = ...

                                                                                                                                                                                                                  Preset effect name to effect ID mapping

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Accessors

                                                                                                                                                                                                                  • get deviceType(): string

                                                                                                                                                                                                                    Get device type (property accessor for convenience)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  • get id(): string | undefined

                                                                                                                                                                                                                    Get device ID (property accessor for convenience)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                                  • get mac(): string | undefined

                                                                                                                                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                                  • get name(): string

                                                                                                                                                                                                                    Get device name (property accessor for convenience)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  Methods

                                                                                                                                                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                    Returns boolean

                                                                                                                                                                                                                  • Register a custom fallback handler

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • handler: FallbackHandler
                                                                                                                                                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  • Set RGB color

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • red: number
                                                                                                                                                                                                                    • green: number
                                                                                                                                                                                                                    • blue: number

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • minTemp: number
                                                                                                                                                                                                                    • maxTemp: number
                                                                                                                                                                                                                    • temp: number

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  • Set preset light effect

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • effectName: string
                                                                                                                                                                                                                    • speed: number = 100

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                    • mode: string | number

                                                                                                                                                                                                                      Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                                  • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                  diff --git a/docs/classes/WoStripLight3.html b/docs/classes/WoStripLight3.html new file mode 100644 index 00000000..be954205 --- /dev/null +++ b/docs/classes/WoStripLight3.html @@ -0,0 +1,103 @@ +WoStripLight3 | node-switchbot
                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                    Class WoStripLight3

                                                                                                                                                                                                                    Strip Light 3 Device +Uses same logic as Color Bulb

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                    Constructors

                                                                                                                                                                                                                    • Parameters

                                                                                                                                                                                                                      • info: DeviceInfo
                                                                                                                                                                                                                      • options: {
                                                                                                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                                                                                            logLevel?: number;
                                                                                                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                                                                                                        } = {}

                                                                                                                                                                                                                      Returns WoStripLight3

                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                    EFFECTS: Record<string, number> = ...

                                                                                                                                                                                                                    Preset effect name to effect ID mapping

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Accessors

                                                                                                                                                                                                                    • get deviceType(): string

                                                                                                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                    • get id(): string | undefined

                                                                                                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                                                    • get mac(): string | undefined

                                                                                                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                                                    • get name(): string

                                                                                                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                    Methods

                                                                                                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                      Returns boolean

                                                                                                                                                                                                                    • Register a custom fallback handler

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • handler: FallbackHandler
                                                                                                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Strip Light 3 and complex light patterns

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex light patterns

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    • Set RGB color

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • red: number
                                                                                                                                                                                                                      • green: number
                                                                                                                                                                                                                      • blue: number

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    • Set color temperature with min/max bounds +For advanced bulbs that support color temperature range control

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • minTemp: number
                                                                                                                                                                                                                      • maxTemp: number
                                                                                                                                                                                                                      • temp: number

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    • Set preset light effect

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • effectName: string
                                                                                                                                                                                                                      • speed: number = 100

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                      • mode: string | number

                                                                                                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                                                    • Verifies the BLE encryption key by attempting a status read with encryption. +Throws an error if the key is invalid or the device rejects the command.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                    diff --git a/docs/classes/WoVacuum.html b/docs/classes/WoVacuum.html new file mode 100644 index 00000000..6322e2fb --- /dev/null +++ b/docs/classes/WoVacuum.html @@ -0,0 +1,98 @@ +WoVacuum | node-switchbot
                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                      Class WoVacuum

                                                                                                                                                                                                                      Vacuum Device

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                      Implements

                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                      Constructors

                                                                                                                                                                                                                      • Parameters

                                                                                                                                                                                                                        • info: DeviceInfo
                                                                                                                                                                                                                        • options: {
                                                                                                                                                                                                                              apiClient?: OpenAPIClient;
                                                                                                                                                                                                                              bleConnection?: BLEConnection;
                                                                                                                                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                              enableFallback?: boolean;
                                                                                                                                                                                                                              enableRetry?: boolean;
                                                                                                                                                                                                                              logLevel?: number;
                                                                                                                                                                                                                              preferredConnection?: ConnectionType;
                                                                                                                                                                                                                              retryConfig?: RetryConfig;
                                                                                                                                                                                                                          } = {}

                                                                                                                                                                                                                        Returns WoVacuum

                                                                                                                                                                                                                      Accessors

                                                                                                                                                                                                                      • get deviceType(): string

                                                                                                                                                                                                                        Get device type (property accessor for convenience)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                      • get id(): string | undefined

                                                                                                                                                                                                                        Get device ID (property accessor for convenience)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                                      • get mac(): string | undefined

                                                                                                                                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                                      • get name(): string

                                                                                                                                                                                                                        Get device name (property accessor for convenience)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                      Methods

                                                                                                                                                                                                                      • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • protocolVersion: number

                                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                        Returns boolean

                                                                                                                                                                                                                      • Register a custom fallback handler

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • handler: FallbackHandler
                                                                                                                                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                        • mode: string | number

                                                                                                                                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                                      diff --git a/docs/classes/WoVacuumK10Plus.html b/docs/classes/WoVacuumK10Plus.html new file mode 100644 index 00000000..4f85c296 --- /dev/null +++ b/docs/classes/WoVacuumK10Plus.html @@ -0,0 +1,98 @@ +WoVacuumK10Plus | node-switchbot
                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                        Class WoVacuumK10Plus

                                                                                                                                                                                                                        Robot Vacuum Cleaner K10+

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                        Constructors

                                                                                                                                                                                                                        • Parameters

                                                                                                                                                                                                                          • info: DeviceInfo
                                                                                                                                                                                                                          • options: {
                                                                                                                                                                                                                                apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                bleConnection?: BLEConnection;
                                                                                                                                                                                                                                circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                enableFallback?: boolean;
                                                                                                                                                                                                                                enableRetry?: boolean;
                                                                                                                                                                                                                                logLevel?: number;
                                                                                                                                                                                                                                preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                retryConfig?: RetryConfig;
                                                                                                                                                                                                                            } = {}

                                                                                                                                                                                                                          Returns WoVacuumK10Plus

                                                                                                                                                                                                                        Accessors

                                                                                                                                                                                                                        • get deviceType(): string

                                                                                                                                                                                                                          Get device type (property accessor for convenience)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                                        • get id(): string | undefined

                                                                                                                                                                                                                          Get device ID (property accessor for convenience)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                                                        • get mac(): string | undefined

                                                                                                                                                                                                                          Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns string | undefined

                                                                                                                                                                                                                        • get name(): string

                                                                                                                                                                                                                          Get device name (property accessor for convenience)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                                        Methods

                                                                                                                                                                                                                        • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • protocolVersion: number

                                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                                        • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                                                        • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                          Returns boolean

                                                                                                                                                                                                                        • Register a custom fallback handler

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • handler: FallbackHandler
                                                                                                                                                                                                                          • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                          Returns string

                                                                                                                                                                                                                        • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • protocolVersion: number

                                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                                        • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                                        • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                          Returns Promise<boolean>

                                                                                                                                                                                                                        • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                          • mode: string | number

                                                                                                                                                                                                                            Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                          Returns Promise<CommandResult>

                                                                                                                                                                                                                        diff --git a/docs/classes/WoVacuumK10Pro.html b/docs/classes/WoVacuumK10Pro.html new file mode 100644 index 00000000..b85d9ab4 --- /dev/null +++ b/docs/classes/WoVacuumK10Pro.html @@ -0,0 +1,98 @@ +WoVacuumK10Pro | node-switchbot
                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                          Class WoVacuumK10Pro

                                                                                                                                                                                                                          Robot Vacuum Cleaner K10+ Pro

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                          Constructors

                                                                                                                                                                                                                          • Parameters

                                                                                                                                                                                                                            • info: DeviceInfo
                                                                                                                                                                                                                            • options: {
                                                                                                                                                                                                                                  apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                  bleConnection?: BLEConnection;
                                                                                                                                                                                                                                  circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                  enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                  enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                  enableFallback?: boolean;
                                                                                                                                                                                                                                  enableRetry?: boolean;
                                                                                                                                                                                                                                  logLevel?: number;
                                                                                                                                                                                                                                  preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                  retryConfig?: RetryConfig;
                                                                                                                                                                                                                              } = {}

                                                                                                                                                                                                                            Returns WoVacuumK10Pro

                                                                                                                                                                                                                          Accessors

                                                                                                                                                                                                                          • get deviceType(): string

                                                                                                                                                                                                                            Get device type (property accessor for convenience)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                                          • get id(): string | undefined

                                                                                                                                                                                                                            Get device ID (property accessor for convenience)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                                                                          • get mac(): string | undefined

                                                                                                                                                                                                                            Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns string | undefined

                                                                                                                                                                                                                          • get name(): string

                                                                                                                                                                                                                            Get device name (property accessor for convenience)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                                          Methods

                                                                                                                                                                                                                          • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • protocolVersion: number

                                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                                          • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                                                                          • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                            Returns boolean

                                                                                                                                                                                                                          • Register a custom fallback handler

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • handler: FallbackHandler
                                                                                                                                                                                                                            • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                            Returns string

                                                                                                                                                                                                                          • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • protocolVersion: number

                                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                                          • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                                          • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                            Returns Promise<boolean>

                                                                                                                                                                                                                          • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                            • mode: string | number

                                                                                                                                                                                                                              Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                            Returns Promise<CommandResult>

                                                                                                                                                                                                                          diff --git a/docs/classes/WoVacuumK10ProCombo.html b/docs/classes/WoVacuumK10ProCombo.html new file mode 100644 index 00000000..52d92c97 --- /dev/null +++ b/docs/classes/WoVacuumK10ProCombo.html @@ -0,0 +1,98 @@ +WoVacuumK10ProCombo | node-switchbot
                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                            Class WoVacuumK10ProCombo

                                                                                                                                                                                                                            Robot Vacuum Cleaner K10+ Pro Combo

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                            Constructors

                                                                                                                                                                                                                            • Parameters

                                                                                                                                                                                                                              • info: DeviceInfo
                                                                                                                                                                                                                              • options: {
                                                                                                                                                                                                                                    apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                    bleConnection?: BLEConnection;
                                                                                                                                                                                                                                    circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                    enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                    enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                    enableFallback?: boolean;
                                                                                                                                                                                                                                    enableRetry?: boolean;
                                                                                                                                                                                                                                    logLevel?: number;
                                                                                                                                                                                                                                    preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                    retryConfig?: RetryConfig;
                                                                                                                                                                                                                                } = {}

                                                                                                                                                                                                                              Returns WoVacuumK10ProCombo

                                                                                                                                                                                                                            Accessors

                                                                                                                                                                                                                            • get deviceType(): string

                                                                                                                                                                                                                              Get device type (property accessor for convenience)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                                            • get id(): string | undefined

                                                                                                                                                                                                                              Get device ID (property accessor for convenience)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                                                            • get mac(): string | undefined

                                                                                                                                                                                                                              Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns string | undefined

                                                                                                                                                                                                                            • get name(): string

                                                                                                                                                                                                                              Get device name (property accessor for convenience)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                                            Methods

                                                                                                                                                                                                                            • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • protocolVersion: number

                                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                                            • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                                                            • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                              Returns boolean

                                                                                                                                                                                                                            • Register a custom fallback handler

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • handler: FallbackHandler
                                                                                                                                                                                                                              • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                              Returns string

                                                                                                                                                                                                                            • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • protocolVersion: number

                                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                                            • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                                            • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                              Returns Promise<boolean>

                                                                                                                                                                                                                            • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Parameters

                                                                                                                                                                                                                              • mode: string | number

                                                                                                                                                                                                                                Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                              Returns Promise<CommandResult>

                                                                                                                                                                                                                            diff --git a/docs/classes/WoVacuumK11Plus.html b/docs/classes/WoVacuumK11Plus.html new file mode 100644 index 00000000..05da61f1 --- /dev/null +++ b/docs/classes/WoVacuumK11Plus.html @@ -0,0 +1,98 @@ +WoVacuumK11Plus | node-switchbot
                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                              Class WoVacuumK11Plus

                                                                                                                                                                                                                              Robot Vacuum Cleaner K11+

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                              Constructors

                                                                                                                                                                                                                              • Parameters

                                                                                                                                                                                                                                • info: DeviceInfo
                                                                                                                                                                                                                                • options: {
                                                                                                                                                                                                                                      apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                      bleConnection?: BLEConnection;
                                                                                                                                                                                                                                      circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                      enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                      enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                      enableFallback?: boolean;
                                                                                                                                                                                                                                      enableRetry?: boolean;
                                                                                                                                                                                                                                      logLevel?: number;
                                                                                                                                                                                                                                      preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                      retryConfig?: RetryConfig;
                                                                                                                                                                                                                                  } = {}

                                                                                                                                                                                                                                Returns WoVacuumK11Plus

                                                                                                                                                                                                                              Accessors

                                                                                                                                                                                                                              • get deviceType(): string

                                                                                                                                                                                                                                Get device type (property accessor for convenience)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                                              • get id(): string | undefined

                                                                                                                                                                                                                                Get device ID (property accessor for convenience)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns string | undefined

                                                                                                                                                                                                                              • get mac(): string | undefined

                                                                                                                                                                                                                                Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns string | undefined

                                                                                                                                                                                                                              • get name(): string

                                                                                                                                                                                                                                Get device name (property accessor for convenience)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                                              Methods

                                                                                                                                                                                                                              • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • protocolVersion: number

                                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                                              • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                                                                                                              • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                                Returns boolean

                                                                                                                                                                                                                              • Register a custom fallback handler

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • handler: FallbackHandler
                                                                                                                                                                                                                                • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                                Returns string

                                                                                                                                                                                                                              • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • protocolVersion: number

                                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                                              • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                                              • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                Returns Promise<boolean>

                                                                                                                                                                                                                              • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Parameters

                                                                                                                                                                                                                                • mode: string | number

                                                                                                                                                                                                                                  Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                Returns Promise<CommandResult>

                                                                                                                                                                                                                              diff --git a/docs/classes/WoVacuumK20.html b/docs/classes/WoVacuumK20.html new file mode 100644 index 00000000..b8937077 --- /dev/null +++ b/docs/classes/WoVacuumK20.html @@ -0,0 +1,98 @@ +WoVacuumK20 | node-switchbot
                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                Class WoVacuumK20

                                                                                                                                                                                                                                Robot Vacuum Cleaner K20

                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                Constructors

                                                                                                                                                                                                                                • Parameters

                                                                                                                                                                                                                                  • info: DeviceInfo
                                                                                                                                                                                                                                  • options: {
                                                                                                                                                                                                                                        apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                        bleConnection?: BLEConnection;
                                                                                                                                                                                                                                        circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                        enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                        enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                        enableFallback?: boolean;
                                                                                                                                                                                                                                        enableRetry?: boolean;
                                                                                                                                                                                                                                        logLevel?: number;
                                                                                                                                                                                                                                        preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                        retryConfig?: RetryConfig;
                                                                                                                                                                                                                                    } = {}

                                                                                                                                                                                                                                  Returns WoVacuumK20

                                                                                                                                                                                                                                Accessors

                                                                                                                                                                                                                                • get deviceType(): string

                                                                                                                                                                                                                                  Get device type (property accessor for convenience)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                                                • get id(): string | undefined

                                                                                                                                                                                                                                  Get device ID (property accessor for convenience)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                                                                • get mac(): string | undefined

                                                                                                                                                                                                                                  Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns string | undefined

                                                                                                                                                                                                                                • get name(): string

                                                                                                                                                                                                                                  Get device name (property accessor for convenience)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                                                Methods

                                                                                                                                                                                                                                • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • protocolVersion: number

                                                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                                                • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                                                                • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                                  Returns boolean

                                                                                                                                                                                                                                • Register a custom fallback handler

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • handler: FallbackHandler
                                                                                                                                                                                                                                  • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                                  Returns string

                                                                                                                                                                                                                                • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • protocolVersion: number

                                                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                                                • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                                                • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                  Returns Promise<boolean>

                                                                                                                                                                                                                                • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Parameters

                                                                                                                                                                                                                                  • mode: string | number

                                                                                                                                                                                                                                    Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                  Returns Promise<CommandResult>

                                                                                                                                                                                                                                diff --git a/docs/classes/WoVacuumS10.html b/docs/classes/WoVacuumS10.html new file mode 100644 index 00000000..bcb90283 --- /dev/null +++ b/docs/classes/WoVacuumS10.html @@ -0,0 +1,98 @@ +WoVacuumS10 | node-switchbot
                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                  Class WoVacuumS10

                                                                                                                                                                                                                                  Robot Vacuum Cleaner S10

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                  Constructors

                                                                                                                                                                                                                                  • Parameters

                                                                                                                                                                                                                                    • info: DeviceInfo
                                                                                                                                                                                                                                    • options: {
                                                                                                                                                                                                                                          apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                          bleConnection?: BLEConnection;
                                                                                                                                                                                                                                          circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                          enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                          enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                          enableFallback?: boolean;
                                                                                                                                                                                                                                          enableRetry?: boolean;
                                                                                                                                                                                                                                          logLevel?: number;
                                                                                                                                                                                                                                          preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                          retryConfig?: RetryConfig;
                                                                                                                                                                                                                                      } = {}

                                                                                                                                                                                                                                    Returns WoVacuumS10

                                                                                                                                                                                                                                  Accessors

                                                                                                                                                                                                                                  • get deviceType(): string

                                                                                                                                                                                                                                    Get device type (property accessor for convenience)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                                  • get id(): string | undefined

                                                                                                                                                                                                                                    Get device ID (property accessor for convenience)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                                                  • get mac(): string | undefined

                                                                                                                                                                                                                                    Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns string | undefined

                                                                                                                                                                                                                                  • get name(): string

                                                                                                                                                                                                                                    Get device name (property accessor for convenience)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                                  Methods

                                                                                                                                                                                                                                  • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • protocolVersion: number

                                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                                  • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                                                  • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                                    Returns boolean

                                                                                                                                                                                                                                  • Register a custom fallback handler

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • handler: FallbackHandler
                                                                                                                                                                                                                                    • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                                    Returns string

                                                                                                                                                                                                                                  • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • protocolVersion: number

                                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                                  • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                                  • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                    Returns Promise<boolean>

                                                                                                                                                                                                                                  • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Parameters

                                                                                                                                                                                                                                    • mode: string | number

                                                                                                                                                                                                                                      Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                    Returns Promise<CommandResult>

                                                                                                                                                                                                                                  diff --git a/docs/classes/WoVacuumS20.html b/docs/classes/WoVacuumS20.html new file mode 100644 index 00000000..776b9caa --- /dev/null +++ b/docs/classes/WoVacuumS20.html @@ -0,0 +1,98 @@ +WoVacuumS20 | node-switchbot
                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                    Class WoVacuumS20

                                                                                                                                                                                                                                    Robot Vacuum Cleaner S20

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                    Constructors

                                                                                                                                                                                                                                    • Parameters

                                                                                                                                                                                                                                      • info: DeviceInfo
                                                                                                                                                                                                                                      • options: {
                                                                                                                                                                                                                                            apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                            bleConnection?: BLEConnection;
                                                                                                                                                                                                                                            circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                                                                                                            logLevel?: number;
                                                                                                                                                                                                                                            preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                            retryConfig?: RetryConfig;
                                                                                                                                                                                                                                        } = {}

                                                                                                                                                                                                                                      Returns WoVacuumS20

                                                                                                                                                                                                                                    Accessors

                                                                                                                                                                                                                                    • get deviceType(): string

                                                                                                                                                                                                                                      Get device type (property accessor for convenience)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                                    • get id(): string | undefined

                                                                                                                                                                                                                                      Get device ID (property accessor for convenience)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                                                                    • get mac(): string | undefined

                                                                                                                                                                                                                                      Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns string | undefined

                                                                                                                                                                                                                                    • get name(): string

                                                                                                                                                                                                                                      Get device name (property accessor for convenience)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                                    Methods

                                                                                                                                                                                                                                    • Start cleaning (BLE-first, API-fallback)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • protocolVersion: number

                                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                                    • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                                                                    • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                                      Returns boolean

                                                                                                                                                                                                                                    • Register a custom fallback handler

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • handler: FallbackHandler
                                                                                                                                                                                                                                      • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                                      Returns string

                                                                                                                                                                                                                                    • Return to dock (BLE-first, API-fallback)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • protocolVersion: number

                                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                                    • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                                    • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                      Returns Promise<boolean>

                                                                                                                                                                                                                                    • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Parameters

                                                                                                                                                                                                                                      • mode: string | number

                                                                                                                                                                                                                                        Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                      Returns Promise<CommandResult>

                                                                                                                                                                                                                                    diff --git a/docs/classes/WoWaterDetector.html b/docs/classes/WoWaterDetector.html new file mode 100644 index 00000000..6ec62518 --- /dev/null +++ b/docs/classes/WoWaterDetector.html @@ -0,0 +1,116 @@ +WoWaterDetector | node-switchbot
                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                      Class WoWaterDetector

                                                                                                                                                                                                                                      Base class for all SwitchBot devices

                                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                                      This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices:

                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                      • BLE-first, API-fallback: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by preferredConnection and enableFallback.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • Centralized Fallback: The getStatusWithFallback() and sendCommand() methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • Connection Intelligence: Tracks connection health and performance, automatically preferring the most reliable connection if enabled.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • Circuit Breaker & Retry: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                      • For status: Call await this.getStatusWithFallback(normalizeBLE, normalizeAPI) in your getStatus() implementation.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • For commands: Use await this.sendCommand(bleCommand, apiCommand, apiParameter) to automatically select the best connection and handle fallback.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency.
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      async getStatus(): Promise<DeviceStatus> {
                                                                                                                                                                                                                                      return this.getStatusWithFallback(
                                                                                                                                                                                                                                      bleData => ({ ... }), // normalize BLE data
                                                                                                                                                                                                                                      apiData => ({ ... }), // normalize API data
                                                                                                                                                                                                                                      )
                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                      async turnOn(): Promise<boolean> {
                                                                                                                                                                                                                                      const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn')
                                                                                                                                                                                                                                      return result.success
                                                                                                                                                                                                                                      } +
                                                                                                                                                                                                                                      + + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                      • preferredConnection: 'ble' | 'api' (default: 'ble')
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • enableFallback: boolean (default: true)
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • enableConnectionIntelligence: boolean (default: true)
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • enableCircuitBreaker: boolean (default: true)
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • enableRetry: boolean (default: true)
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                      • getStatusWithFallback()
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • sendCommand()
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • hasBLE(), hasAPI()
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • setPreferredConnection(), setFallbackEnabled()
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      This pattern ensures all device classes benefit from robust, testable, and consistent connection logic.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                      Constructors

                                                                                                                                                                                                                                      • Parameters

                                                                                                                                                                                                                                        • info: DeviceInfo
                                                                                                                                                                                                                                        • options: {
                                                                                                                                                                                                                                              apiClient?: OpenAPIClient;
                                                                                                                                                                                                                                              bleConnection?: BLEConnection;
                                                                                                                                                                                                                                              circuitBreakerConfig?: CircuitBreakerConfig;
                                                                                                                                                                                                                                              enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                              enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                              enableFallback?: boolean;
                                                                                                                                                                                                                                              enableRetry?: boolean;
                                                                                                                                                                                                                                              logLevel?: number;
                                                                                                                                                                                                                                              preferredConnection?: ConnectionType;
                                                                                                                                                                                                                                              retryConfig?: RetryConfig;
                                                                                                                                                                                                                                          } = {}

                                                                                                                                                                                                                                        Returns WoWaterDetector

                                                                                                                                                                                                                                      Accessors

                                                                                                                                                                                                                                      • get deviceType(): string

                                                                                                                                                                                                                                        Get device type (property accessor for convenience)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                                      • get id(): string | undefined

                                                                                                                                                                                                                                        Get device ID (property accessor for convenience)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                                                      • get mac(): string | undefined

                                                                                                                                                                                                                                        Get MAC address (property accessor for convenience)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns string | undefined

                                                                                                                                                                                                                                      • get name(): string

                                                                                                                                                                                                                                        Get device name (property accessor for convenience)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                                      Methods

                                                                                                                                                                                                                                      • Get basic device info (universal settings retrieval) +Returns: battery, firmware, device-specific settings, etc. +Command: 0x57 0x02 (BLE), 'getBasicInfo' (API)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Example usage: +const info = await device.getBasicInfo(); +console.log(info);

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns a CommandResult object with device info fields.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                                                      • Returns true if device should be polled (passive polling interval elapsed)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                                        • interval: number = PASSIVE_POLL_INTERVAL

                                                                                                                                                                                                                                        Returns boolean

                                                                                                                                                                                                                                      • Register a custom fallback handler

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                                        • handler: FallbackHandler
                                                                                                                                                                                                                                        • Optionaloptions: FallbackHandlerOptions

                                                                                                                                                                                                                                        Returns string

                                                                                                                                                                                                                                      • Send multiple commands in sequence (all must succeed) +Used for Curtain 3, bulbs, strips, and other multi-step devices

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                                                      • Send multiple commands (returns true if any succeed) +Used for fallback operations with complex patterns

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                                        • commands: (() => Promise<boolean>)[]

                                                                                                                                                                                                                                        Returns Promise<boolean>

                                                                                                                                                                                                                                      • Universal mode setting command +BLE: 0x57 0x03 [modeByte] +API: 'setMode' (if available)

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Parameters

                                                                                                                                                                                                                                        • mode: string | number

                                                                                                                                                                                                                                          Mode value (number or string, per-device enum recommended)

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          Example usage: +await device.setMode('auto') +await device.setMode(1)

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          Returns a CommandResult object indicating success and mode info.

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                        Returns Promise<CommandResult>

                                                                                                                                                                                                                                      diff --git a/docs/enums/LogLevel.html b/docs/enums/LogLevel.html index f9055116..c92fe4d0 100644 --- a/docs/enums/LogLevel.html +++ b/docs/enums/LogLevel.html @@ -1,10 +1,7 @@ -LogLevel | node-switchbot
                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                        Enumeration LogLevel

                                                                                                                                                                                                                                        Enum for log levels.

                                                                                                                                                                                                                                        -
                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                        Enumeration Members

                                                                                                                                                                                                                                        DEBUG -DEBUGERROR -DEBUGSUCCESS -DEBUGWARN +LogLevel | node-switchbot
                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                          Enumeration LogLevel

                                                                                                                                                                                                                                          Log levels for debugging and diagnostics

                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                          Enumeration Members

                                                                                                                                                                                                                                          Enumeration Members

                                                                                                                                                                                                                                          DEBUG: "debug"
                                                                                                                                                                                                                                          DEBUGERROR: "debugerror"
                                                                                                                                                                                                                                          DEBUGSUCCESS: "debugsuccess"
                                                                                                                                                                                                                                          DEBUGWARN: "debugwarn"
                                                                                                                                                                                                                                          ERROR: "error"
                                                                                                                                                                                                                                          INFO: "info"
                                                                                                                                                                                                                                          SUCCESS: "success"
                                                                                                                                                                                                                                          WARN: "warn"
                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          Enumeration Members

                                                                                                                                                                                                                                          DEBUG: 4
                                                                                                                                                                                                                                          ERROR: 1
                                                                                                                                                                                                                                          INFO: 3
                                                                                                                                                                                                                                          NONE: 0
                                                                                                                                                                                                                                          WARN: 2
                                                                                                                                                                                                                                          diff --git a/docs/enums/SwitchBotBLEModel.html b/docs/enums/SwitchBotBLEModel.html index b367c173..e62d28b9 100644 --- a/docs/enums/SwitchBotBLEModel.html +++ b/docs/enums/SwitchBotBLEModel.html @@ -1,5 +1,7 @@ -SwitchBotBLEModel | node-switchbot
                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                            Enumeration SwitchBotBLEModel

                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                            Enumeration Members

                                                                                                                                                                                                                                            AirPurifier +SwitchBotBLEModel | node-switchbot
                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                              Enumeration SwitchBotBLEModel

                                                                                                                                                                                                                                              SwitchBot BLE Model identifiers

                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                              Enumeration Members

                                                                                                                                                                                                                                              AirPurifier: "+"
                                                                                                                                                                                                                                              AirPurifierTable: "7"
                                                                                                                                                                                                                                              BlindTilt: "x"
                                                                                                                                                                                                                                              Bot: "H"
                                                                                                                                                                                                                                              CeilingLight: "q"
                                                                                                                                                                                                                                              CeilingLightPro: "n"
                                                                                                                                                                                                                                              ColorBulb: "u"
                                                                                                                                                                                                                                              ContactSensor: "d"
                                                                                                                                                                                                                                              Curtain: "c"
                                                                                                                                                                                                                                              Curtain3: "{"
                                                                                                                                                                                                                                              Hub2: "v"
                                                                                                                                                                                                                                              Hub3: "V"
                                                                                                                                                                                                                                              Humidifier: "e"
                                                                                                                                                                                                                                              Humidifier2: "#"
                                                                                                                                                                                                                                              Keypad: "y"
                                                                                                                                                                                                                                              Leak: "&"
                                                                                                                                                                                                                                              Lock: "o"
                                                                                                                                                                                                                                              LockPro: "$"
                                                                                                                                                                                                                                              Meter: "T"
                                                                                                                                                                                                                                              MeterPlus: "i"
                                                                                                                                                                                                                                              MeterPro: "4"
                                                                                                                                                                                                                                              MeterProCO2: "5"
                                                                                                                                                                                                                                              MotionSensor: "s"
                                                                                                                                                                                                                                              OutdoorMeter: "w"
                                                                                                                                                                                                                                              PlugMiniJP: "j"
                                                                                                                                                                                                                                              PlugMiniUS: "g"
                                                                                                                                                                                                                                              PresenceSensor: "p"
                                                                                                                                                                                                                                              RelaySwitch1: ";"
                                                                                                                                                                                                                                              RelaySwitch1PM: "<"
                                                                                                                                                                                                                                              Remote: "b"
                                                                                                                                                                                                                                              StripLight: "r"
                                                                                                                                                                                                                                              Unknown: "Unknown"
                                                                                                                                                                                                                                              +WaterLeakDetector +

                                                                                                                                                                                                                                              Enumeration Members

                                                                                                                                                                                                                                              AirPurifier: "\b"
                                                                                                                                                                                                                                              AirPurifierTable: "\t"
                                                                                                                                                                                                                                              BatteryCirculatorFan: "\u0004"
                                                                                                                                                                                                                                              BlindTilt: "x"
                                                                                                                                                                                                                                              Bot: "H"
                                                                                                                                                                                                                                              CeilingLight: "q"
                                                                                                                                                                                                                                              CeilingLightPro: "r"
                                                                                                                                                                                                                                              ColorBulb: "u"
                                                                                                                                                                                                                                              ContactSensor: "d"
                                                                                                                                                                                                                                              Curtain: "c"
                                                                                                                                                                                                                                              Curtain3: "{"
                                                                                                                                                                                                                                              Hub2: "\u0001"
                                                                                                                                                                                                                                              Hub3: "\u0002"
                                                                                                                                                                                                                                              Humidifier: "e"
                                                                                                                                                                                                                                              Humidifier2: "\u0007"
                                                                                                                                                                                                                                              K10ProComboK10Pro: "\u0010"
                                                                                                                                                                                                                                              Keypad: "k"
                                                                                                                                                                                                                                              KeypadTouch: "\u000b"
                                                                                                                                                                                                                                              Lock: "o"
                                                                                                                                                                                                                                              LockPro: "\u0011"
                                                                                                                                                                                                                                              Meter: "T"
                                                                                                                                                                                                                                              MeterPlus: "i"
                                                                                                                                                                                                                                              MeterPro: "o"
                                                                                                                                                                                                                                              MeterProCO2: "w"
                                                                                                                                                                                                                                              MotionSensor: "s"
                                                                                                                                                                                                                                              OutdoorMeter: "n"
                                                                                                                                                                                                                                              Plug: "g"
                                                                                                                                                                                                                                              PlugMiniJP: "j"
                                                                                                                                                                                                                                              PlugMiniUS: "j"
                                                                                                                                                                                                                                              PresenceSensor: "\u0006"
                                                                                                                                                                                                                                              RelaySwitch1: "\u000e"
                                                                                                                                                                                                                                              RelaySwitch1PM: "\r"
                                                                                                                                                                                                                                              Remote: "\u0005"
                                                                                                                                                                                                                                              RobotVacuumCleanerK10Plus: "\u000f"
                                                                                                                                                                                                                                              RobotVacuumCleanerS1: "\n"
                                                                                                                                                                                                                                              RobotVacuumCleanerS1Plus: "\f"
                                                                                                                                                                                                                                              StripLight: "p"
                                                                                                                                                                                                                                              WaterLeakDetector: "y"
                                                                                                                                                                                                                                              diff --git a/docs/enums/SwitchBotBLEModelFriendlyName.html b/docs/enums/SwitchBotBLEModelFriendlyName.html deleted file mode 100644 index ed82d0b7..00000000 --- a/docs/enums/SwitchBotBLEModelFriendlyName.html +++ /dev/null @@ -1,38 +0,0 @@ -SwitchBotBLEModelFriendlyName | node-switchbot
                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                Enumeration SwitchBotBLEModelFriendlyName

                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                Enumeration Members

                                                                                                                                                                                                                                                AirPurifier: "Air Purifier"
                                                                                                                                                                                                                                                AirPurifierPM2_5: "Air Purifier PM2.5"
                                                                                                                                                                                                                                                AirPurifierTable: "Air Purifier Table"
                                                                                                                                                                                                                                                AirPurifierTablePM2_5: "Air Purifier Table PM2.5"
                                                                                                                                                                                                                                                AirPurifierTableVOC: "Air Purifier Table VOC"
                                                                                                                                                                                                                                                AirPurifierVOC: "Air Purifier VOC"
                                                                                                                                                                                                                                                BatteryCirculatorFan: "Battery Circulator Fan"
                                                                                                                                                                                                                                                BlindTilt: "Blind Tilt"
                                                                                                                                                                                                                                                Bot: "Bot"
                                                                                                                                                                                                                                                CeilingLight: "Ceiling Light"
                                                                                                                                                                                                                                                CeilingLightPro: "Ceiling Light Pro"
                                                                                                                                                                                                                                                CirculatorFan: "Circulator Fan"
                                                                                                                                                                                                                                                ColorBulb: "Color Bulb"
                                                                                                                                                                                                                                                ContactSensor: "Contact Sensor"
                                                                                                                                                                                                                                                Curtain: "Curtain"
                                                                                                                                                                                                                                                Curtain3: "Curtain 3"
                                                                                                                                                                                                                                                Hub2: "Hub 2"
                                                                                                                                                                                                                                                Hub3: "Hub 3"
                                                                                                                                                                                                                                                Humidifier: "Humidifier"
                                                                                                                                                                                                                                                Humidifier2: "Humidifier2"
                                                                                                                                                                                                                                                Keypad: "Keypad"
                                                                                                                                                                                                                                                Leak: "Water Detector"
                                                                                                                                                                                                                                                Lock: "Lock"
                                                                                                                                                                                                                                                LockPro: "Lock Pro"
                                                                                                                                                                                                                                                Meter: "Meter"
                                                                                                                                                                                                                                                MeterPlus: "Meter Plus"
                                                                                                                                                                                                                                                MeterPro: "Meter Pro"
                                                                                                                                                                                                                                                MeterProCO2: "Meter Pro CO2"
                                                                                                                                                                                                                                                MotionSensor: "Motion Sensor"
                                                                                                                                                                                                                                                OutdoorMeter: "Outdoor Meter"
                                                                                                                                                                                                                                                PlugMini: "Plug Mini"
                                                                                                                                                                                                                                                PresenceSensor: "Presence Sensor"
                                                                                                                                                                                                                                                RelaySwitch1: "Relay Switch 1"
                                                                                                                                                                                                                                                RelaySwitch1PM: "Relay Switch 1PM"
                                                                                                                                                                                                                                                Remote: "Remote"
                                                                                                                                                                                                                                                StripLight: "Strip Light"
                                                                                                                                                                                                                                                Unknown: "Unknown"
                                                                                                                                                                                                                                                diff --git a/docs/enums/SwitchBotBLEModelName.html b/docs/enums/SwitchBotBLEModelName.html index 5cbdfe7c..aae72995 100644 --- a/docs/enums/SwitchBotBLEModelName.html +++ b/docs/enums/SwitchBotBLEModelName.html @@ -1,5 +1,7 @@ -SwitchBotBLEModelName | node-switchbot
                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                  Enumeration SwitchBotBLEModelName

                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                  Enumeration Members

                                                                                                                                                                                                                                                  AirPurifier +SwitchBotBLEModelName | node-switchbot
                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                    Enumeration SwitchBotBLEModelName

                                                                                                                                                                                                                                                    SwitchBot BLE Model Names

                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                    Enumeration Members

                                                                                                                                                                                                                                                    AirPurifier: "WoAirPurifier"
                                                                                                                                                                                                                                                    AirPurifierTable: "WoAirPurifierTable"
                                                                                                                                                                                                                                                    BlindTilt: "WoBlindTilt"
                                                                                                                                                                                                                                                    Bot: "WoHand"
                                                                                                                                                                                                                                                    CeilingLight: "WoCeilingLight"
                                                                                                                                                                                                                                                    CeilingLightPro: "WoCeilingLightPro"
                                                                                                                                                                                                                                                    ColorBulb: "WoBulb"
                                                                                                                                                                                                                                                    ContactSensor: "WoContact"
                                                                                                                                                                                                                                                    Curtain: "WoCurtain"
                                                                                                                                                                                                                                                    Curtain3: "WoCurtain3"
                                                                                                                                                                                                                                                    Hub2: "WoHub2"
                                                                                                                                                                                                                                                    Hub3: "WoHub3"
                                                                                                                                                                                                                                                    Humidifier: "WoHumi"
                                                                                                                                                                                                                                                    Humidifier2: "WoHumi2"
                                                                                                                                                                                                                                                    Keypad: "WoKeypad"
                                                                                                                                                                                                                                                    Leak: "WoLeakDetector"
                                                                                                                                                                                                                                                    Lock: "WoSmartLock"
                                                                                                                                                                                                                                                    LockPro: "WoSmartLockPro"
                                                                                                                                                                                                                                                    Meter: "WoSensorTH"
                                                                                                                                                                                                                                                    MeterPlus: "WoSensorTHPlus"
                                                                                                                                                                                                                                                    MeterPro: "WoSensorTHP"
                                                                                                                                                                                                                                                    MeterProCO2: "WoSensorTHPc"
                                                                                                                                                                                                                                                    MotionSensor: "WoMotion"
                                                                                                                                                                                                                                                    OutdoorMeter: "WoIOSensorTH"
                                                                                                                                                                                                                                                    PlugMini: "WoPlugMini"
                                                                                                                                                                                                                                                    PresenceSensor: "WoPresence"
                                                                                                                                                                                                                                                    RelaySwitch1: "WoRelaySwitch1Plus"
                                                                                                                                                                                                                                                    RelaySwitch1PM: "WoRelaySwitch1PM"
                                                                                                                                                                                                                                                    Remote: "WoRemote"
                                                                                                                                                                                                                                                    StripLight: "WoStrip"
                                                                                                                                                                                                                                                    Unknown: "Unknown"
                                                                                                                                                                                                                                                    +WaterLeakDetector +

                                                                                                                                                                                                                                                    Enumeration Members

                                                                                                                                                                                                                                                    AirPurifier: "WoAirPurifier"
                                                                                                                                                                                                                                                    AirPurifierTable: "WoAirPurifierTable"
                                                                                                                                                                                                                                                    BatteryCirculatorFan: "WoCirculatorFan"
                                                                                                                                                                                                                                                    BlindTilt: "WoBlindTilt"
                                                                                                                                                                                                                                                    Bot: "WoHand"
                                                                                                                                                                                                                                                    CeilingLight: "WoCeilingLight"
                                                                                                                                                                                                                                                    CeilingLightPro: "WoCeilingLightPro"
                                                                                                                                                                                                                                                    ColorBulb: "WoBulb"
                                                                                                                                                                                                                                                    ContactSensor: "WoContact"
                                                                                                                                                                                                                                                    Curtain: "WoCurtain"
                                                                                                                                                                                                                                                    Curtain3: "WoCurtain3"
                                                                                                                                                                                                                                                    Hub2: "WoHub2"
                                                                                                                                                                                                                                                    Hub3: "WoHub3"
                                                                                                                                                                                                                                                    Humidifier: "WoHumi"
                                                                                                                                                                                                                                                    Humidifier2: "WoHumi2"
                                                                                                                                                                                                                                                    K10ProComboK10Pro: "WoVacK10ProCombo"
                                                                                                                                                                                                                                                    Keypad: "WoKeypad"
                                                                                                                                                                                                                                                    KeypadTouch: "WoKeypadTouch"
                                                                                                                                                                                                                                                    Lock: "WoSmartLock"
                                                                                                                                                                                                                                                    LockPro: "WoSmartLockPro"
                                                                                                                                                                                                                                                    Meter: "WoSensorTH"
                                                                                                                                                                                                                                                    MeterPlus: "WoSensorTHPlus"
                                                                                                                                                                                                                                                    MeterPro: "WoSensorTHPro"
                                                                                                                                                                                                                                                    MeterProCO2: "WoSensorTHProCO2"
                                                                                                                                                                                                                                                    MotionSensor: "WoMotion"
                                                                                                                                                                                                                                                    OutdoorMeter: "WoIOSensorTH"
                                                                                                                                                                                                                                                    Plug: "WoPlugUS"
                                                                                                                                                                                                                                                    PlugMiniJP: "WoPlugMiniJP"
                                                                                                                                                                                                                                                    PlugMiniUS: "WoPlugMiniUS"
                                                                                                                                                                                                                                                    PresenceSensor: "WoPresence"
                                                                                                                                                                                                                                                    RelaySwitch1: "WoRelaySwitch1"
                                                                                                                                                                                                                                                    RelaySwitch1PM: "WoRelaySwitch1PM"
                                                                                                                                                                                                                                                    Remote: "WoRemote"
                                                                                                                                                                                                                                                    RobotVacuumCleanerK10Plus: "WoVacK10Plus"
                                                                                                                                                                                                                                                    RobotVacuumCleanerS1: "WoVacS1"
                                                                                                                                                                                                                                                    RobotVacuumCleanerS1Plus: "WoVacS1Plus"
                                                                                                                                                                                                                                                    StripLight: "WoStrip"
                                                                                                                                                                                                                                                    WaterLeakDetector: "WoLeak"
                                                                                                                                                                                                                                                    diff --git a/docs/enums/SwitchBotModel.html b/docs/enums/SwitchBotModel.html deleted file mode 100644 index 5ccfcb8f..00000000 --- a/docs/enums/SwitchBotModel.html +++ /dev/null @@ -1,51 +0,0 @@ -SwitchBotModel | node-switchbot
                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                      Enumeration SwitchBotModel

                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                      Enumeration Members

                                                                                                                                                                                                                                                      AirPurifier: "W5302300"
                                                                                                                                                                                                                                                      AirPurifierTable: "W5302310"
                                                                                                                                                                                                                                                      BatteryCirculatorFan: "W3800510"
                                                                                                                                                                                                                                                      BlindTilt: "W2701600"
                                                                                                                                                                                                                                                      Bot: "SwitchBot S1"
                                                                                                                                                                                                                                                      CeilingLight: "W2612230/W2612240"
                                                                                                                                                                                                                                                      CeilingLightPro: "W2612210/W2612220"
                                                                                                                                                                                                                                                      CirculatorFan: "W3800511"
                                                                                                                                                                                                                                                      ColorBulb: "W1401400"
                                                                                                                                                                                                                                                      ContactSensor: "W1201500"
                                                                                                                                                                                                                                                      Curtain: "W0701600"
                                                                                                                                                                                                                                                      Curtain3: "W2400000"
                                                                                                                                                                                                                                                      Hub2: "W3202100"
                                                                                                                                                                                                                                                      Hub3: "W3302100"
                                                                                                                                                                                                                                                      HubMini: "W0202200"
                                                                                                                                                                                                                                                      HubPlus: "SwitchBot Hub S1"
                                                                                                                                                                                                                                                      Humidifier: "W0801800"
                                                                                                                                                                                                                                                      Humidifier2: "WXXXXXXX"
                                                                                                                                                                                                                                                      IndoorCam: "W1301200"
                                                                                                                                                                                                                                                      K10: "K10+"
                                                                                                                                                                                                                                                      K10Pro: "K10+ Pro"
                                                                                                                                                                                                                                                      Keypad: "W2500010"
                                                                                                                                                                                                                                                      KeypadTouch: "W2500020"
                                                                                                                                                                                                                                                      Lock: "W1601700"
                                                                                                                                                                                                                                                      LockPro: "W3500000"
                                                                                                                                                                                                                                                      Meter: "SwitchBot MeterTH S1"
                                                                                                                                                                                                                                                      MeterPlusJP: "W2201500"
                                                                                                                                                                                                                                                      MeterPlusUS: "W2301500"
                                                                                                                                                                                                                                                      MeterPro: "W4900000"
                                                                                                                                                                                                                                                      MeterProCO2: "W4900010"
                                                                                                                                                                                                                                                      MotionSensor: "W1101500"
                                                                                                                                                                                                                                                      OutdoorMeter: "W3400010"
                                                                                                                                                                                                                                                      PanTiltCam: "W1801200"
                                                                                                                                                                                                                                                      PanTiltCam2K: "W3101100"
                                                                                                                                                                                                                                                      Plug: "SP11"
                                                                                                                                                                                                                                                      PlugMiniJP: "W2001400/W2001401"
                                                                                                                                                                                                                                                      PlugMiniUS: "W1901400/W1901401"
                                                                                                                                                                                                                                                      PresenceSensor: "W8200000"
                                                                                                                                                                                                                                                      RelaySwitch1: "W5502300"
                                                                                                                                                                                                                                                      RelaySwitch1PM: "W5502310"
                                                                                                                                                                                                                                                      Remote: "Remote"
                                                                                                                                                                                                                                                      RobotVacuumCleanerS1: "W3011000"
                                                                                                                                                                                                                                                      RobotVacuumCleanerS10: "W3211800"
                                                                                                                                                                                                                                                      RobotVacuumCleanerS1Plus: "W3011010"
                                                                                                                                                                                                                                                      StripLight: "W1701100"
                                                                                                                                                                                                                                                      UniversalRemote: "UniversalRemote"
                                                                                                                                                                                                                                                      Unknown: "Unknown"
                                                                                                                                                                                                                                                      WaterDetector: "W4402000"
                                                                                                                                                                                                                                                      WoSweeper: "WoSweeper"
                                                                                                                                                                                                                                                      WoSweeperMini: "WoSweeperMini"
                                                                                                                                                                                                                                                      diff --git a/docs/functions/updateBaseURL.html b/docs/functions/updateBaseURL.html index 02bb9c74..52ff0cb4 100644 --- a/docs/functions/updateBaseURL.html +++ b/docs/functions/updateBaseURL.html @@ -1,3 +1,3 @@ -updateBaseURL | node-switchbot
                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                        Function updateBaseURL

                                                                                                                                                                                                                                                        • Updates the base URL for the SwitchBot API endpoints.

                                                                                                                                                                                                                                                          -

                                                                                                                                                                                                                                                          Parameters

                                                                                                                                                                                                                                                          • newBaseURL: string

                                                                                                                                                                                                                                                            The new base URL to use.

                                                                                                                                                                                                                                                            -

                                                                                                                                                                                                                                                          Returns void

                                                                                                                                                                                                                                                        +updateBaseURL | node-switchbot
                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                          Function updateBaseURL

                                                                                                                                                                                                                                                          • Update the base URL for all API endpoints

                                                                                                                                                                                                                                                            +

                                                                                                                                                                                                                                                            Parameters

                                                                                                                                                                                                                                                            • newBaseURL: string

                                                                                                                                                                                                                                                              The new base URL to use

                                                                                                                                                                                                                                                              +

                                                                                                                                                                                                                                                            Returns void

                                                                                                                                                                                                                                                          diff --git a/docs/hierarchy.html b/docs/hierarchy.html index 750540fa..60c20d93 100644 --- a/docs/hierarchy.html +++ b/docs/hierarchy.html @@ -1 +1 @@ -node-switchbot
                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                            Preparing search index...
                                                                                                                                                                                                                                                            +node-switchbot
                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                              node-switchbot

                                                                                                                                                                                                                                                              Hierarchy Summary

                                                                                                                                                                                                                                                              diff --git a/docs/index.html b/docs/index.html index 5969ec3d..dd3493c6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,21 +1,55 @@ node-switchbot
                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                node-switchbot

                                                                                                                                                                                                                                                                node-switchbot

                                                                                                                                                                                                                                                                -

                                                                                                                                                                                                                                                                Node-SwitchBot

                                                                                                                                                                                                                                                                npm version +

                                                                                                                                                                                                                                                                Node-SwitchBot

                                                                                                                                                                                                                                                                +

                                                                                                                                                                                                                                                                npm version npm downloads

                                                                                                                                                                                                                                                                The node-switchbot is a Node.js module that allows you to interact with various SwitchBot devices. You can control your SwitchBot (Bot)'s arm, operate your SwitchBot Curtain, and manage your SwitchBot Lock. Additionally, you can monitor temperature and humidity using the SwitchBot Thermometer & Hygrometer (Meter), and check the status of the SwitchBot Motion Sensor and SwitchBot Contact Sensor.

                                                                                                                                                                                                                                                                This module now supports both Bluetooth Low Energy (BLE) and the SwitchBot OpenAPI, providing more flexibility and options for interacting with your devices.

                                                                                                                                                                                                                                                                Please note that most of this module was developed by referencing the official BLE API and OpenAPI documentation. However, some functionalities were developed through trial and error, so there might be inaccuracies in the information obtained from this module.


                                                                                                                                                                                                                                                                -

                                                                                                                                                                                                                                                                To install the node-switchbot module within your project, use the following command:

                                                                                                                                                                                                                                                                + +

                                                                                                                                                                                                                                                                To install the node-switchbot module within your project, use the following command:

                                                                                                                                                                                                                                                                $ npm install --save node-switchbot
                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                -

                                                                                                                                                                                                                                                                To see a breakdown of how to use the BLE functionality of this project, visit the BLE (Bluetooth Low Energy) documentation.

                                                                                                                                                                                                                                                                -

                                                                                                                                                                                                                                                                To see a breakdown of how to use the OpenAPI functionality of this project, visit the OpenAPI documentation.

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                                                  v4.0.0 introduces a unified hybrid approach that automatically uses BLE when available with seamless API fallback.

                                                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                                                  import { SwitchBot } from 'node-switchbot'

                                                                                                                                                                                                                                                                  const switchbot = new SwitchBot({
                                                                                                                                                                                                                                                                  token: 'YOUR_TOKEN', // OpenAPI token (optional for BLE-only)
                                                                                                                                                                                                                                                                  secret: 'YOUR_SECRET', // OpenAPI secret (optional for BLE-only)
                                                                                                                                                                                                                                                                  enableBLE: true, // Enable BLE discovery (Linux/macOS)
                                                                                                                                                                                                                                                                  enableFallback: true, // Auto-fallback between BLE/API
                                                                                                                                                                                                                                                                  })

                                                                                                                                                                                                                                                                  // Discover all devices (BLE + API)
                                                                                                                                                                                                                                                                  const devices = await switchbot.discover()

                                                                                                                                                                                                                                                                  // Control devices
                                                                                                                                                                                                                                                                  const bot = switchbot.devices.get('YOUR_DEVICE_ID')
                                                                                                                                                                                                                                                                  await bot.press()

                                                                                                                                                                                                                                                                  // Get status
                                                                                                                                                                                                                                                                  const status = await bot.getStatus()
                                                                                                                                                                                                                                                                  console.log(status)

                                                                                                                                                                                                                                                                  // Cleanup
                                                                                                                                                                                                                                                                  await switchbot.cleanup() +
                                                                                                                                                                                                                                                                  + + +
                                                                                                                                                                                                                                                                  // Bot - Press/Switch control
                                                                                                                                                                                                                                                                  await bot.turnOn()
                                                                                                                                                                                                                                                                  await bot.turnOff()
                                                                                                                                                                                                                                                                  await bot.press()

                                                                                                                                                                                                                                                                  // Bot with Password Protection (BLE only)
                                                                                                                                                                                                                                                                  const protectedBot = new WoHand({ id: 'YOUR_BOT_ID', password: 'A1b2' })
                                                                                                                                                                                                                                                                  await protectedBot.setPassword('A1b2') // Set 4-char alphanumeric password
                                                                                                                                                                                                                                                                  await protectedBot.press() // Commands are automatically encrypted
                                                                                                                                                                                                                                                                  await protectedBot.clearPassword() // Remove password protection

                                                                                                                                                                                                                                                                  // Curtain - Position control
                                                                                                                                                                                                                                                                  await curtain.open()
                                                                                                                                                                                                                                                                  await curtain.close()
                                                                                                                                                                                                                                                                  await curtain.setPosition(50) // 50% open

                                                                                                                                                                                                                                                                  // Lock - Lock/Unlock
                                                                                                                                                                                                                                                                  await lock.lock()
                                                                                                                                                                                                                                                                  await lock.unlock()

                                                                                                                                                                                                                                                                  // Bulb - Color and brightness
                                                                                                                                                                                                                                                                  await bulb.turnOn()
                                                                                                                                                                                                                                                                  await bulb.setBrightness(80)
                                                                                                                                                                                                                                                                  await bulb.setColor(255, 0, 0) // Red

                                                                                                                                                                                                                                                                  // Meter - Read sensors
                                                                                                                                                                                                                                                                  const meterStatus = await meter.getStatus()
                                                                                                                                                                                                                                                                  console.log(meterStatus.temperature, meterStatus.humidity) +
                                                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                                                  See the examples directory for more usage patterns.

                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                                                  To see a breakdown of how to use the BLE functionality of this project, visit the BLE (Bluetooth Low Energy) documentation.

                                                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                                                  To see a breakdown of how to use the OpenAPI functionality of this project, visit the OpenAPI documentation.

                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                                                  Breaking Changes in v4.0.0:

                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                  • Unified API: Single SwitchBot class replaces separate SwitchBotBLE and SwitchBotOpenAPI classes
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  • 🔄 Automatic Discovery: Combined BLE + OpenAPI discovery in one call
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  • 🛡️ Automatic Fallback: BLE commands automatically fall back to API on failure
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  • 📦 Device Manager: Access devices via switchbot.devices.get(id) instead of direct discovery results
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  • 🏷️ TypeScript: Full TypeScript rewrite with comprehensive type definitions
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  • ⚠️ No Backward Compatibility: v3.x APIs are not supported - migration required
                                                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                                                  Migration Example:

                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                  // v3.x (old)
                                                                                                                                                                                                                                                                  import { SwitchBotBLE, SwitchBotOpenAPI } from 'node-switchbot'
                                                                                                                                                                                                                                                                  const ble = new SwitchBotBLE()
                                                                                                                                                                                                                                                                  const api = new SwitchBotOpenAPI(token, secret)

                                                                                                                                                                                                                                                                  // v4.0.0 (new)
                                                                                                                                                                                                                                                                  import { SwitchBot } from 'node-switchbot'
                                                                                                                                                                                                                                                                  const switchbot = new SwitchBot({ token, secret, enableBLE: true }) +
                                                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                                                  + + -
                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/APICommandRequest.html b/docs/interfaces/APICommandRequest.html new file mode 100644 index 00000000..6e094eb2 --- /dev/null +++ b/docs/interfaces/APICommandRequest.html @@ -0,0 +1,5 @@ +APICommandRequest | node-switchbot
                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                  Interface APICommandRequest

                                                                                                                                                                                                                                                                  Command request to OpenAPI

                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                  interface APICommandRequest {
                                                                                                                                                                                                                                                                      command: string;
                                                                                                                                                                                                                                                                      commandType?: string;
                                                                                                                                                                                                                                                                      parameter?: any;
                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                  command: string
                                                                                                                                                                                                                                                                  commandType?: string
                                                                                                                                                                                                                                                                  parameter?: any
                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/APICommandResponse.html b/docs/interfaces/APICommandResponse.html new file mode 100644 index 00000000..3ec6d785 --- /dev/null +++ b/docs/interfaces/APICommandResponse.html @@ -0,0 +1,5 @@ +APICommandResponse | node-switchbot
                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                    Interface APICommandResponse

                                                                                                                                                                                                                                                                    Command response from OpenAPI

                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                    interface APICommandResponse {
                                                                                                                                                                                                                                                                        body: any;
                                                                                                                                                                                                                                                                        message: string;
                                                                                                                                                                                                                                                                        statusCode: number;
                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                    body: any
                                                                                                                                                                                                                                                                    message: string
                                                                                                                                                                                                                                                                    statusCode: number
                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/APIDevice.html b/docs/interfaces/APIDevice.html new file mode 100644 index 00000000..9dac86ed --- /dev/null +++ b/docs/interfaces/APIDevice.html @@ -0,0 +1,18 @@ +APIDevice | node-switchbot
                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                      Interface APIDevice

                                                                                                                                                                                                                                                                      Device information from OpenAPI

                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                      interface APIDevice {
                                                                                                                                                                                                                                                                          calibrate?: boolean;
                                                                                                                                                                                                                                                                          curtainDevicesIds?: string[];
                                                                                                                                                                                                                                                                          deviceId: string;
                                                                                                                                                                                                                                                                          deviceName: string;
                                                                                                                                                                                                                                                                          deviceType: string;
                                                                                                                                                                                                                                                                          enableCloudService: boolean;
                                                                                                                                                                                                                                                                          group?: boolean;
                                                                                                                                                                                                                                                                          groupName?: string;
                                                                                                                                                                                                                                                                          hubDeviceId: string;
                                                                                                                                                                                                                                                                          keyList?: {
                                                                                                                                                                                                                                                                              createTime: number;
                                                                                                                                                                                                                                                                              id: number;
                                                                                                                                                                                                                                                                              keyId: string;
                                                                                                                                                                                                                                                                              name: string;
                                                                                                                                                                                                                                                                              status: "enabled" | "disabled";
                                                                                                                                                                                                                                                                              type: string;
                                                                                                                                                                                                                                                                          }[];
                                                                                                                                                                                                                                                                          lockType?: "unlatch"
                                                                                                                                                                                                                                                                          | "latch";
                                                                                                                                                                                                                                                                          master?: boolean;
                                                                                                                                                                                                                                                                          moving?: boolean;
                                                                                                                                                                                                                                                                          openDirection?: "left" | "right";
                                                                                                                                                                                                                                                                          slidePosition?: number;
                                                                                                                                                                                                                                                                          version?: string;
                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                      calibrate?: boolean
                                                                                                                                                                                                                                                                      curtainDevicesIds?: string[]
                                                                                                                                                                                                                                                                      deviceId: string
                                                                                                                                                                                                                                                                      deviceName: string
                                                                                                                                                                                                                                                                      deviceType: string
                                                                                                                                                                                                                                                                      enableCloudService: boolean
                                                                                                                                                                                                                                                                      group?: boolean
                                                                                                                                                                                                                                                                      groupName?: string
                                                                                                                                                                                                                                                                      hubDeviceId: string
                                                                                                                                                                                                                                                                      keyList?: {
                                                                                                                                                                                                                                                                          createTime: number;
                                                                                                                                                                                                                                                                          id: number;
                                                                                                                                                                                                                                                                          keyId: string;
                                                                                                                                                                                                                                                                          name: string;
                                                                                                                                                                                                                                                                          status: "enabled" | "disabled";
                                                                                                                                                                                                                                                                          type: string;
                                                                                                                                                                                                                                                                      }[]
                                                                                                                                                                                                                                                                      lockType?: "unlatch" | "latch"
                                                                                                                                                                                                                                                                      master?: boolean
                                                                                                                                                                                                                                                                      moving?: boolean
                                                                                                                                                                                                                                                                      openDirection?: "left" | "right"
                                                                                                                                                                                                                                                                      slidePosition?: number
                                                                                                                                                                                                                                                                      version?: string
                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/APIDeviceStatus.html b/docs/interfaces/APIDeviceStatus.html new file mode 100644 index 00000000..2823dcf7 --- /dev/null +++ b/docs/interfaces/APIDeviceStatus.html @@ -0,0 +1,36 @@ +APIDeviceStatus | node-switchbot
                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                        Interface APIDeviceStatus

                                                                                                                                                                                                                                                                        Device status from OpenAPI

                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                        interface APIDeviceStatus {
                                                                                                                                                                                                                                                                            airMode?: "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                            auto?: boolean;
                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                            botMode?: "press" | "switch" | "customize";
                                                                                                                                                                                                                                                                            brightnessLevel?: number;
                                                                                                                                                                                                                                                                            calibrate?: boolean;
                                                                                                                                                                                                                                                                            childLock?: boolean;
                                                                                                                                                                                                                                                                            color?: string;
                                                                                                                                                                                                                                                                            colorTemperature?: number;
                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                            deviceType: string;
                                                                                                                                                                                                                                                                            doorState?: "opened" | "closed" | "unknown";
                                                                                                                                                                                                                                                                            electricCurrent?: number;
                                                                                                                                                                                                                                                                            electricityOfDay?: number;
                                                                                                                                                                                                                                                                            fanSpeed?: number;
                                                                                                                                                                                                                                                                            group?: boolean;
                                                                                                                                                                                                                                                                            hubDeviceId: string;
                                                                                                                                                                                                                                                                            humidity?: number;
                                                                                                                                                                                                                                                                            lackWater?: boolean;
                                                                                                                                                                                                                                                                            lightLevel?: number | "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                            lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                            moveDetected?: boolean;
                                                                                                                                                                                                                                                                            moving?: boolean;
                                                                                                                                                                                                                                                                            nebulizationEfficiency?: number;
                                                                                                                                                                                                                                                                            openState?: "closed" | "open" | "timeout";
                                                                                                                                                                                                                                                                            pm25?: number;
                                                                                                                                                                                                                                                                            power?: "on" | "off";
                                                                                                                                                                                                                                                                            slidePosition?: number;
                                                                                                                                                                                                                                                                            sound?: boolean;
                                                                                                                                                                                                                                                                            temperature?: number;
                                                                                                                                                                                                                                                                            version?: string;
                                                                                                                                                                                                                                                                            voltage?: number;
                                                                                                                                                                                                                                                                            waterLeakDetected?: boolean;
                                                                                                                                                                                                                                                                            weight?: number;
                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                        airMode?: "auto" | "manual" | "sleep"
                                                                                                                                                                                                                                                                        auto?: boolean
                                                                                                                                                                                                                                                                        battery?: number
                                                                                                                                                                                                                                                                        botMode?: "press" | "switch" | "customize"
                                                                                                                                                                                                                                                                        brightnessLevel?: number
                                                                                                                                                                                                                                                                        calibrate?: boolean
                                                                                                                                                                                                                                                                        childLock?: boolean
                                                                                                                                                                                                                                                                        color?: string
                                                                                                                                                                                                                                                                        colorTemperature?: number
                                                                                                                                                                                                                                                                        deviceId: string
                                                                                                                                                                                                                                                                        deviceType: string
                                                                                                                                                                                                                                                                        doorState?: "opened" | "closed" | "unknown"
                                                                                                                                                                                                                                                                        electricCurrent?: number
                                                                                                                                                                                                                                                                        electricityOfDay?: number
                                                                                                                                                                                                                                                                        fanSpeed?: number
                                                                                                                                                                                                                                                                        group?: boolean
                                                                                                                                                                                                                                                                        hubDeviceId: string
                                                                                                                                                                                                                                                                        humidity?: number
                                                                                                                                                                                                                                                                        lackWater?: boolean
                                                                                                                                                                                                                                                                        lightLevel?: number | "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                        lockState?: "locked" | "unlocked" | "jammed"
                                                                                                                                                                                                                                                                        moveDetected?: boolean
                                                                                                                                                                                                                                                                        moving?: boolean
                                                                                                                                                                                                                                                                        nebulizationEfficiency?: number
                                                                                                                                                                                                                                                                        openState?: "closed" | "open" | "timeout"
                                                                                                                                                                                                                                                                        pm25?: number
                                                                                                                                                                                                                                                                        power?: "on" | "off"
                                                                                                                                                                                                                                                                        slidePosition?: number
                                                                                                                                                                                                                                                                        sound?: boolean
                                                                                                                                                                                                                                                                        temperature?: number
                                                                                                                                                                                                                                                                        version?: string
                                                                                                                                                                                                                                                                        voltage?: number
                                                                                                                                                                                                                                                                        waterLeakDetected?: boolean
                                                                                                                                                                                                                                                                        weight?: number
                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/APIErrorResponse.html b/docs/interfaces/APIErrorResponse.html new file mode 100644 index 00000000..23ff4eb2 --- /dev/null +++ b/docs/interfaces/APIErrorResponse.html @@ -0,0 +1,5 @@ +APIErrorResponse | node-switchbot
                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                          Interface APIErrorResponse

                                                                                                                                                                                                                                                                          OpenAPI error response

                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                          interface APIErrorResponse {
                                                                                                                                                                                                                                                                              body?: any;
                                                                                                                                                                                                                                                                              message: string;
                                                                                                                                                                                                                                                                              statusCode: number;
                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                          body?: any
                                                                                                                                                                                                                                                                          message: string
                                                                                                                                                                                                                                                                          statusCode: number
                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/APIResponse.html b/docs/interfaces/APIResponse.html new file mode 100644 index 00000000..0cb52a07 --- /dev/null +++ b/docs/interfaces/APIResponse.html @@ -0,0 +1,5 @@ +APIResponse | node-switchbot
                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                            Interface APIResponse<T>

                                                                                                                                                                                                                                                                            OpenAPI Response base

                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                            interface APIResponse<T = any> {
                                                                                                                                                                                                                                                                                body: T;
                                                                                                                                                                                                                                                                                message: string;
                                                                                                                                                                                                                                                                                statusCode: number;
                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                            Type Parameters

                                                                                                                                                                                                                                                                            • T = any
                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                            body: T
                                                                                                                                                                                                                                                                            message: string
                                                                                                                                                                                                                                                                            statusCode: number
                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/AdvertisementData.html b/docs/interfaces/AdvertisementData.html deleted file mode 100644 index 2cba737b..00000000 --- a/docs/interfaces/AdvertisementData.html +++ /dev/null @@ -1,3 +0,0 @@ -AdvertisementData | node-switchbot
                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                              Interface AdvertisementData

                                                                                                                                                                                                                                                                              interface AdvertisementData {
                                                                                                                                                                                                                                                                                  manufacturerData: null | Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                  serviceData: null | Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                              manufacturerData: null | Buffer<ArrayBufferLike>
                                                                                                                                                                                                                                                                              serviceData: null | Buffer<ArrayBufferLike>
                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/AirPurifierCommands.html b/docs/interfaces/AirPurifierCommands.html new file mode 100644 index 00000000..8cced657 --- /dev/null +++ b/docs/interfaces/AirPurifierCommands.html @@ -0,0 +1,6 @@ +AirPurifierCommands | node-switchbot
                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                Interface AirPurifierCommands

                                                                                                                                                                                                                                                                                interface AirPurifierCommands {
                                                                                                                                                                                                                                                                                    setFanSpeed: (speed: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                    setMode: (mode: "auto" | "manual" | "sleep") => Promise<CommandResult>;
                                                                                                                                                                                                                                                                                    setPresetMode?: (
                                                                                                                                                                                                                                                                                        mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet",
                                                                                                                                                                                                                                                                                    ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                    turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                    turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                Implemented by

                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                setFanSpeed: (speed: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                setMode: (mode: "auto" | "manual" | "sleep") => Promise<CommandResult>
                                                                                                                                                                                                                                                                                setPresetMode?: (
                                                                                                                                                                                                                                                                                    mode: "auto" | "sleep" | "level_1" | "level_2" | "level_3" | "pet",
                                                                                                                                                                                                                                                                                ) => Promise<boolean>
                                                                                                                                                                                                                                                                                turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/AirPurifierServiceData.html b/docs/interfaces/AirPurifierServiceData.html new file mode 100644 index 00000000..4ef87474 --- /dev/null +++ b/docs/interfaces/AirPurifierServiceData.html @@ -0,0 +1,29 @@ +AirPurifierServiceData | node-switchbot
                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                  Interface AirPurifierServiceData

                                                                                                                                                                                                                                                                                  Air Purifier BLE Service Data

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  interface AirPurifierServiceData {
                                                                                                                                                                                                                                                                                      battery?: number;
                                                                                                                                                                                                                                                                                      channel2State?: boolean;
                                                                                                                                                                                                                                                                                      doorOpen?: boolean;
                                                                                                                                                                                                                                                                                      fanSpeed: number;
                                                                                                                                                                                                                                                                                      inMotion?: boolean;
                                                                                                                                                                                                                                                                                      lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                      mode: "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                      model: string;
                                                                                                                                                                                                                                                                                      modelName: string;
                                                                                                                                                                                                                                                                                      pm25?: number;
                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                      sequenceNumber?: number;
                                                                                                                                                                                                                                                                                      state: boolean;
                                                                                                                                                                                                                                                                                      status?: number;
                                                                                                                                                                                                                                                                                      [key: string]: unknown;
                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                  Indexable

                                                                                                                                                                                                                                                                                  • [key: string]: unknown

                                                                                                                                                                                                                                                                                    Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                  battery?: number

                                                                                                                                                                                                                                                                                  Battery level (0-100)

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  channel2State?: boolean

                                                                                                                                                                                                                                                                                  Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  doorOpen?: boolean

                                                                                                                                                                                                                                                                                  Parsed door-open flag where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  fanSpeed: number
                                                                                                                                                                                                                                                                                  inMotion?: boolean

                                                                                                                                                                                                                                                                                  Parsed movement state where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                  Parsed lock state where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  mode: "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                  Parsed mode where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  model: string

                                                                                                                                                                                                                                                                                  Device model

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  modelName: string

                                                                                                                                                                                                                                                                                  Model name string

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  pm25?: number
                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                  Raw service data buffer

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  sequenceNumber?: number

                                                                                                                                                                                                                                                                                  Parsed sequence number where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  state: boolean

                                                                                                                                                                                                                                                                                  Parsed on/off state where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  status?: number

                                                                                                                                                                                                                                                                                  Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/AirPurifierStatus.html b/docs/interfaces/AirPurifierStatus.html new file mode 100644 index 00000000..62601d78 --- /dev/null +++ b/docs/interfaces/AirPurifierStatus.html @@ -0,0 +1,17 @@ +AirPurifierStatus | node-switchbot
                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                    Interface AirPurifierStatus

                                                                                                                                                                                                                                                                                    Air Purifier specific types

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    interface AirPurifierStatus {
                                                                                                                                                                                                                                                                                        airQuality?: "excellent" | "good" | "fair" | "poor";
                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                        connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                        deviceId: string;
                                                                                                                                                                                                                                                                                        fanSpeed?: number;
                                                                                                                                                                                                                                                                                        mode?: "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                        pm25?: number;
                                                                                                                                                                                                                                                                                        power: "on" | "off";
                                                                                                                                                                                                                                                                                        updatedAt?: Date;
                                                                                                                                                                                                                                                                                        version?: string;
                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                    airQuality?: "excellent" | "good" | "fair" | "poor"
                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    connectionType: ConnectionType

                                                                                                                                                                                                                                                                                    Connection type used to retrieve status

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    deviceId: string

                                                                                                                                                                                                                                                                                    Device ID

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    fanSpeed?: number
                                                                                                                                                                                                                                                                                    mode?: "auto" | "manual" | "sleep"
                                                                                                                                                                                                                                                                                    pm25?: number
                                                                                                                                                                                                                                                                                    power: "on" | "off"
                                                                                                                                                                                                                                                                                    updatedAt?: Date

                                                                                                                                                                                                                                                                                    Last updated timestamp

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    version?: string

                                                                                                                                                                                                                                                                                    Firmware version

                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/BLEAdvertisement.html b/docs/interfaces/BLEAdvertisement.html new file mode 100644 index 00000000..a70e417d --- /dev/null +++ b/docs/interfaces/BLEAdvertisement.html @@ -0,0 +1,13 @@ +BLEAdvertisement | node-switchbot
                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                      Interface BLEAdvertisement

                                                                                                                                                                                                                                                                                      BLE Device Advertisement

                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                      interface BLEAdvertisement {
                                                                                                                                                                                                                                                                                          address?: string;
                                                                                                                                                                                                                                                                                          id: string;
                                                                                                                                                                                                                                                                                          isAddressable: boolean;
                                                                                                                                                                                                                                                                                          isEncrypted?: boolean;
                                                                                                                                                                                                                                                                                          modelFriendlyName?: string;
                                                                                                                                                                                                                                                                                          rawAdvData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                          rssi: number;
                                                                                                                                                                                                                                                                                          serviceData: BLEServiceData;
                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                      address?: string
                                                                                                                                                                                                                                                                                      id: string
                                                                                                                                                                                                                                                                                      isAddressable: boolean
                                                                                                                                                                                                                                                                                      isEncrypted?: boolean

                                                                                                                                                                                                                                                                                      True if advertisement is encrypted

                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                      modelFriendlyName?: string

                                                                                                                                                                                                                                                                                      User-friendly model name (e.g., "WoHand")

                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                      rawAdvData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                      Raw BLE advertisement data (entire buffer)

                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                      rssi: number
                                                                                                                                                                                                                                                                                      serviceData: BLEServiceData
                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/BLEScanOptions.html b/docs/interfaces/BLEScanOptions.html new file mode 100644 index 00000000..f5a92ab6 --- /dev/null +++ b/docs/interfaces/BLEScanOptions.html @@ -0,0 +1,10 @@ +BLEScanOptions | node-switchbot
                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                        Interface BLEScanOptions

                                                                                                                                                                                                                                                                                        BLE Scanner options

                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                        interface BLEScanOptions {
                                                                                                                                                                                                                                                                                            active?: boolean;
                                                                                                                                                                                                                                                                                            duration?: number;
                                                                                                                                                                                                                                                                                            macs?: string[];
                                                                                                                                                                                                                                                                                            model?: string;
                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                        active?: boolean

                                                                                                                                                                                                                                                                                        Active scanning (default: true)

                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                        duration?: number

                                                                                                                                                                                                                                                                                        Scan duration in milliseconds

                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                        macs?: string[]

                                                                                                                                                                                                                                                                                        Filter by specific MAC addresses

                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                        model?: string

                                                                                                                                                                                                                                                                                        Filter by device model

                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/BLEServiceData.html b/docs/interfaces/BLEServiceData.html new file mode 100644 index 00000000..9e146637 --- /dev/null +++ b/docs/interfaces/BLEServiceData.html @@ -0,0 +1,27 @@ +BLEServiceData | node-switchbot
                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                          Interface BLEServiceData

                                                                                                                                                                                                                                                                                          BLE Service Data for various SwitchBot devices

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          interface BLEServiceData {
                                                                                                                                                                                                                                                                                              battery?: number;
                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                              state?: boolean;
                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                          battery?: number

                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          state?: boolean

                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/BlindTiltCommands.html b/docs/interfaces/BlindTiltCommands.html new file mode 100644 index 00000000..23a955f5 --- /dev/null +++ b/docs/interfaces/BlindTiltCommands.html @@ -0,0 +1,7 @@ +BlindTiltCommands | node-switchbot
                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                            Interface BlindTiltCommands

                                                                                                                                                                                                                                                                                            interface BlindTiltCommands {
                                                                                                                                                                                                                                                                                                close: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                closeDown: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                closeUp: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                open: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                pause: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                setPosition: (position: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                            Implemented by

                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                            close: () => Promise<boolean>
                                                                                                                                                                                                                                                                                            closeDown: () => Promise<boolean>
                                                                                                                                                                                                                                                                                            closeUp: () => Promise<boolean>
                                                                                                                                                                                                                                                                                            open: () => Promise<boolean>
                                                                                                                                                                                                                                                                                            pause: () => Promise<boolean>
                                                                                                                                                                                                                                                                                            setPosition: (position: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/BlindTiltServiceData.html b/docs/interfaces/BlindTiltServiceData.html new file mode 100644 index 00000000..c947135e --- /dev/null +++ b/docs/interfaces/BlindTiltServiceData.html @@ -0,0 +1,30 @@ +BlindTiltServiceData | node-switchbot
                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                              Interface BlindTiltServiceData

                                                                                                                                                                                                                                                                                              Blind Tilt BLE Service Data

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              interface BlindTiltServiceData {
                                                                                                                                                                                                                                                                                                  battery: number;
                                                                                                                                                                                                                                                                                                  calibration: boolean;
                                                                                                                                                                                                                                                                                                  channel2State?: boolean;
                                                                                                                                                                                                                                                                                                  doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                  inMotion: boolean;
                                                                                                                                                                                                                                                                                                  lightLevel: number;
                                                                                                                                                                                                                                                                                                  lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                  mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                  model: string;
                                                                                                                                                                                                                                                                                                  modelName: string;
                                                                                                                                                                                                                                                                                                  position: number;
                                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                  sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                  state?: boolean;
                                                                                                                                                                                                                                                                                                  status?: number;
                                                                                                                                                                                                                                                                                                  [key: string]: unknown;
                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                              Indexable

                                                                                                                                                                                                                                                                                              • [key: string]: unknown

                                                                                                                                                                                                                                                                                                Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                              battery: number

                                                                                                                                                                                                                                                                                              Battery level (0-100)

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              calibration: boolean
                                                                                                                                                                                                                                                                                              channel2State?: boolean

                                                                                                                                                                                                                                                                                              Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              doorOpen?: boolean

                                                                                                                                                                                                                                                                                              Parsed door-open flag where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              inMotion: boolean

                                                                                                                                                                                                                                                                                              Parsed movement state where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              lightLevel: number
                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                              Parsed lock state where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                              Parsed mode where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              model: string

                                                                                                                                                                                                                                                                                              Device model

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              modelName: string

                                                                                                                                                                                                                                                                                              Model name string

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              position: number
                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                              Raw service data buffer

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              sequenceNumber?: number

                                                                                                                                                                                                                                                                                              Parsed sequence number where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              state?: boolean

                                                                                                                                                                                                                                                                                              Parsed on/off state where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              status?: number

                                                                                                                                                                                                                                                                                              Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/BlindTiltStatus.html b/docs/interfaces/BlindTiltStatus.html new file mode 100644 index 00000000..031439fe --- /dev/null +++ b/docs/interfaces/BlindTiltStatus.html @@ -0,0 +1,16 @@ +BlindTiltStatus | node-switchbot
                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                Interface BlindTiltStatus

                                                                                                                                                                                                                                                                                                Blind Tilt specific types

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                interface BlindTiltStatus {
                                                                                                                                                                                                                                                                                                    battery?: number;
                                                                                                                                                                                                                                                                                                    calibrated?: boolean;
                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                    deviceId: string;
                                                                                                                                                                                                                                                                                                    direction?: "opening" | "closing";
                                                                                                                                                                                                                                                                                                    moving?: boolean;
                                                                                                                                                                                                                                                                                                    position: number;
                                                                                                                                                                                                                                                                                                    updatedAt?: Date;
                                                                                                                                                                                                                                                                                                    version?: string;
                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                battery?: number

                                                                                                                                                                                                                                                                                                Battery level (0-100)

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                calibrated?: boolean
                                                                                                                                                                                                                                                                                                connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                deviceId: string

                                                                                                                                                                                                                                                                                                Device ID

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                direction?: "opening" | "closing"
                                                                                                                                                                                                                                                                                                moving?: boolean
                                                                                                                                                                                                                                                                                                position: number
                                                                                                                                                                                                                                                                                                updatedAt?: Date

                                                                                                                                                                                                                                                                                                Last updated timestamp

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                version?: string

                                                                                                                                                                                                                                                                                                Firmware version

                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/BotCommands.html b/docs/interfaces/BotCommands.html new file mode 100644 index 00000000..72785899 --- /dev/null +++ b/docs/interfaces/BotCommands.html @@ -0,0 +1,8 @@ +BotCommands | node-switchbot
                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                  Interface BotCommands

                                                                                                                                                                                                                                                                                                  interface BotCommands {
                                                                                                                                                                                                                                                                                                      handDown?: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                      handUp?: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                      press: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                      setLongPress?: (duration: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                      setMode?: (mode: "press" | "switch") => Promise<CommandResult>;
                                                                                                                                                                                                                                                                                                      turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                      turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                  Implemented by

                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                  handDown?: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                  handUp?: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                  press: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                  setLongPress?: (duration: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                  setMode?: (mode: "press" | "switch") => Promise<CommandResult>
                                                                                                                                                                                                                                                                                                  turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                  turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/BotServiceData.html b/docs/interfaces/BotServiceData.html new file mode 100644 index 00000000..a50997a6 --- /dev/null +++ b/docs/interfaces/BotServiceData.html @@ -0,0 +1,27 @@ +BotServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                    Interface BotServiceData

                                                                                                                                                                                                                                                                                                    Bot (WoHand) BLE Service Data

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    interface BotServiceData {
                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                        channel2State?: boolean;
                                                                                                                                                                                                                                                                                                        doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                        inMotion?: boolean;
                                                                                                                                                                                                                                                                                                        lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                        mode: "press" | "switch" | "customize";
                                                                                                                                                                                                                                                                                                        model: string;
                                                                                                                                                                                                                                                                                                        modelName: string;
                                                                                                                                                                                                                                                                                                        rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                        sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                        state: boolean;
                                                                                                                                                                                                                                                                                                        status?: number;
                                                                                                                                                                                                                                                                                                        [key: string]: unknown;
                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                    Indexable

                                                                                                                                                                                                                                                                                                    • [key: string]: unknown

                                                                                                                                                                                                                                                                                                      Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                    battery: number

                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    channel2State?: boolean

                                                                                                                                                                                                                                                                                                    Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    doorOpen?: boolean

                                                                                                                                                                                                                                                                                                    Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    inMotion?: boolean

                                                                                                                                                                                                                                                                                                    Parsed movement state where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                    Parsed lock state where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    mode: "press" | "switch" | "customize"

                                                                                                                                                                                                                                                                                                    Parsed mode where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    model: string

                                                                                                                                                                                                                                                                                                    Device model

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    modelName: string

                                                                                                                                                                                                                                                                                                    Model name string

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                    Raw service data buffer

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    sequenceNumber?: number

                                                                                                                                                                                                                                                                                                    Parsed sequence number where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    state: boolean

                                                                                                                                                                                                                                                                                                    Parsed on/off state where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    status?: number

                                                                                                                                                                                                                                                                                                    Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/BotStatus.html b/docs/interfaces/BotStatus.html new file mode 100644 index 00000000..ecd2c67c --- /dev/null +++ b/docs/interfaces/BotStatus.html @@ -0,0 +1,14 @@ +BotStatus | node-switchbot
                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                      Interface BotStatus

                                                                                                                                                                                                                                                                                                      Bot (WoHand) specific types

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      interface BotStatus {
                                                                                                                                                                                                                                                                                                          battery?: number;
                                                                                                                                                                                                                                                                                                          connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                          deviceId: string;
                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize";
                                                                                                                                                                                                                                                                                                          power: "on" | "off";
                                                                                                                                                                                                                                                                                                          updatedAt?: Date;
                                                                                                                                                                                                                                                                                                          version?: string;
                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                      battery?: number

                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                      Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      deviceId: string

                                                                                                                                                                                                                                                                                                      Device ID

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize"
                                                                                                                                                                                                                                                                                                      power: "on" | "off"
                                                                                                                                                                                                                                                                                                      updatedAt?: Date

                                                                                                                                                                                                                                                                                                      Last updated timestamp

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      version?: string

                                                                                                                                                                                                                                                                                                      Firmware version

                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/BulbCommands.html b/docs/interfaces/BulbCommands.html new file mode 100644 index 00000000..43e1c414 --- /dev/null +++ b/docs/interfaces/BulbCommands.html @@ -0,0 +1,10 @@ +BulbCommands | node-switchbot
                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                        Interface BulbCommands

                                                                                                                                                                                                                                                                                                        interface BulbCommands {
                                                                                                                                                                                                                                                                                                            sendCommandSequence?: (
                                                                                                                                                                                                                                                                                                                commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                            ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                            ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            setBrightness: (brightness: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            setColor: (red: number, green: number, blue: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            setColorTemp?: (
                                                                                                                                                                                                                                                                                                                minTemp: number,
                                                                                                                                                                                                                                                                                                                maxTemp: number,
                                                                                                                                                                                                                                                                                                                temp: number,
                                                                                                                                                                                                                                                                                                            ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            setColorTemperature: (temperature: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            setEffect?: (effectName: string, speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                            turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                        Implemented by

                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                        sendCommandSequence?: (commands: (() => Promise<boolean>)[]) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                            commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                        ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        setBrightness: (brightness: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        setColor: (red: number, green: number, blue: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        setColorTemp?: (
                                                                                                                                                                                                                                                                                                            minTemp: number,
                                                                                                                                                                                                                                                                                                            maxTemp: number,
                                                                                                                                                                                                                                                                                                            temp: number,
                                                                                                                                                                                                                                                                                                        ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        setColorTemperature: (temperature: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        setEffect?: (effectName: string, speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                        turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                        turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/BulbServiceData.html b/docs/interfaces/BulbServiceData.html new file mode 100644 index 00000000..2ae22043 --- /dev/null +++ b/docs/interfaces/BulbServiceData.html @@ -0,0 +1,35 @@ +BulbServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                          Interface BulbServiceData

                                                                                                                                                                                                                                                                                                          Bulb BLE Service Data

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          interface BulbServiceData {
                                                                                                                                                                                                                                                                                                              battery?: number;
                                                                                                                                                                                                                                                                                                              blue?: number;
                                                                                                                                                                                                                                                                                                              brightness: number;
                                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                                              colorMode?: boolean;
                                                                                                                                                                                                                                                                                                              colorTemperature?: number;
                                                                                                                                                                                                                                                                                                              delay?: boolean;
                                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                              green?: number;
                                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                                              preset?: boolean;
                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                              red?: number;
                                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                              state: boolean;
                                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                          battery?: number

                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          blue?: number
                                                                                                                                                                                                                                                                                                          brightness: number
                                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          colorMode?: boolean
                                                                                                                                                                                                                                                                                                          colorTemperature?: number
                                                                                                                                                                                                                                                                                                          delay?: boolean
                                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          green?: number
                                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          preset?: boolean
                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          red?: number
                                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          state: boolean

                                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/BulbStatus.html b/docs/interfaces/BulbStatus.html new file mode 100644 index 00000000..38090cd5 --- /dev/null +++ b/docs/interfaces/BulbStatus.html @@ -0,0 +1,16 @@ +BulbStatus | node-switchbot
                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                            Interface BulbStatus

                                                                                                                                                                                                                                                                                                            Bulb/Light specific types

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            interface BulbStatus {
                                                                                                                                                                                                                                                                                                                battery?: number;
                                                                                                                                                                                                                                                                                                                brightness?: number;
                                                                                                                                                                                                                                                                                                                color?: { b: number; g: number; r: number };
                                                                                                                                                                                                                                                                                                                colorTemperature?: number;
                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                deviceId: string;
                                                                                                                                                                                                                                                                                                                power: "on" | "off";
                                                                                                                                                                                                                                                                                                                updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                version?: string;
                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                            battery?: number

                                                                                                                                                                                                                                                                                                            Battery level (0-100)

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            brightness?: number
                                                                                                                                                                                                                                                                                                            color?: { b: number; g: number; r: number }
                                                                                                                                                                                                                                                                                                            colorTemperature?: number
                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                            Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            deviceId: string

                                                                                                                                                                                                                                                                                                            Device ID

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            power: "on" | "off"
                                                                                                                                                                                                                                                                                                            updatedAt?: Date

                                                                                                                                                                                                                                                                                                            Last updated timestamp

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            version?: string

                                                                                                                                                                                                                                                                                                            Firmware version

                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/CeilingLightCommands.html b/docs/interfaces/CeilingLightCommands.html new file mode 100644 index 00000000..bffca660 --- /dev/null +++ b/docs/interfaces/CeilingLightCommands.html @@ -0,0 +1,10 @@ +CeilingLightCommands | node-switchbot
                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                              Interface CeilingLightCommands

                                                                                                                                                                                                                                                                                                              interface CeilingLightCommands {
                                                                                                                                                                                                                                                                                                                  sendCommandSequence?: (
                                                                                                                                                                                                                                                                                                                      commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                  ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                      commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                  ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  setBrightness: (brightness: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  setColor: (red: number, green: number, blue: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  setColorTemp?: (
                                                                                                                                                                                                                                                                                                                      minTemp: number,
                                                                                                                                                                                                                                                                                                                      maxTemp: number,
                                                                                                                                                                                                                                                                                                                      temp: number,
                                                                                                                                                                                                                                                                                                                  ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  setColorTemperature: (temperature: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  setEffect?: (effectName: string, speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                  turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                              sendCommandSequence?: (commands: (() => Promise<boolean>)[]) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                  commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                              ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              setBrightness: (brightness: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              setColor: (red: number, green: number, blue: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              setColorTemp?: (
                                                                                                                                                                                                                                                                                                                  minTemp: number,
                                                                                                                                                                                                                                                                                                                  maxTemp: number,
                                                                                                                                                                                                                                                                                                                  temp: number,
                                                                                                                                                                                                                                                                                                              ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              setColorTemperature: (temperature: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              setEffect?: (effectName: string, speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                              turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                              turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/CeilingLightServiceData.html b/docs/interfaces/CeilingLightServiceData.html new file mode 100644 index 00000000..6c2f7f21 --- /dev/null +++ b/docs/interfaces/CeilingLightServiceData.html @@ -0,0 +1,35 @@ +CeilingLightServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                Interface CeilingLightServiceData

                                                                                                                                                                                                                                                                                                                Ceiling Light BLE Service Data

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                interface CeilingLightServiceData {
                                                                                                                                                                                                                                                                                                                    battery?: number;
                                                                                                                                                                                                                                                                                                                    blue?: number;
                                                                                                                                                                                                                                                                                                                    brightness: number;
                                                                                                                                                                                                                                                                                                                    channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                    colorMode?: boolean;
                                                                                                                                                                                                                                                                                                                    colorTemperature?: number;
                                                                                                                                                                                                                                                                                                                    delay?: boolean;
                                                                                                                                                                                                                                                                                                                    doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                    green?: number;
                                                                                                                                                                                                                                                                                                                    inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                    lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                    mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                    model: string;
                                                                                                                                                                                                                                                                                                                    modelName: string;
                                                                                                                                                                                                                                                                                                                    preset?: boolean;
                                                                                                                                                                                                                                                                                                                    rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                    red?: number;
                                                                                                                                                                                                                                                                                                                    sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                    state: boolean;
                                                                                                                                                                                                                                                                                                                    status?: number;
                                                                                                                                                                                                                                                                                                                    [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                Indexable

                                                                                                                                                                                                                                                                                                                • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                  Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                battery?: number

                                                                                                                                                                                                                                                                                                                Battery level (0-100)

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                blue?: number
                                                                                                                                                                                                                                                                                                                brightness: number
                                                                                                                                                                                                                                                                                                                channel2State?: boolean

                                                                                                                                                                                                                                                                                                                Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                colorMode?: boolean
                                                                                                                                                                                                                                                                                                                colorTemperature?: number
                                                                                                                                                                                                                                                                                                                delay?: boolean
                                                                                                                                                                                                                                                                                                                doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                green?: number
                                                                                                                                                                                                                                                                                                                inMotion?: boolean

                                                                                                                                                                                                                                                                                                                Parsed movement state where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                Parsed lock state where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                Parsed mode where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                model: string

                                                                                                                                                                                                                                                                                                                Device model

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                modelName: string

                                                                                                                                                                                                                                                                                                                Model name string

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                preset?: boolean
                                                                                                                                                                                                                                                                                                                rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                Raw service data buffer

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                red?: number
                                                                                                                                                                                                                                                                                                                sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                state: boolean

                                                                                                                                                                                                                                                                                                                Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                status?: number

                                                                                                                                                                                                                                                                                                                Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/CeilingLightStatus.html b/docs/interfaces/CeilingLightStatus.html new file mode 100644 index 00000000..dccc6a24 --- /dev/null +++ b/docs/interfaces/CeilingLightStatus.html @@ -0,0 +1,16 @@ +CeilingLightStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                  Interface CeilingLightStatus

                                                                                                                                                                                                                                                                                                                  Ceiling Light specific types

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  interface CeilingLightStatus {
                                                                                                                                                                                                                                                                                                                      battery?: number;
                                                                                                                                                                                                                                                                                                                      brightness?: number;
                                                                                                                                                                                                                                                                                                                      color?: { b: number; g: number; r: number };
                                                                                                                                                                                                                                                                                                                      colorTemperature?: number;
                                                                                                                                                                                                                                                                                                                      connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                      deviceId: string;
                                                                                                                                                                                                                                                                                                                      power: "on" | "off";
                                                                                                                                                                                                                                                                                                                      updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                      version?: string;
                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                  battery?: number

                                                                                                                                                                                                                                                                                                                  Battery level (0-100)

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  brightness?: number
                                                                                                                                                                                                                                                                                                                  color?: { b: number; g: number; r: number }
                                                                                                                                                                                                                                                                                                                  colorTemperature?: number
                                                                                                                                                                                                                                                                                                                  connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                  Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  deviceId: string

                                                                                                                                                                                                                                                                                                                  Device ID

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  power: "on" | "off"
                                                                                                                                                                                                                                                                                                                  updatedAt?: Date

                                                                                                                                                                                                                                                                                                                  Last updated timestamp

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  version?: string

                                                                                                                                                                                                                                                                                                                  Firmware version

                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/Chars.html b/docs/interfaces/Chars.html deleted file mode 100644 index 87613f1f..00000000 --- a/docs/interfaces/Chars.html +++ /dev/null @@ -1,4 +0,0 @@ -Chars | node-switchbot
                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                    Interface Chars

                                                                                                                                                                                                                                                                                                                    interface Chars {
                                                                                                                                                                                                                                                                                                                        device: null | Characteristic;
                                                                                                                                                                                                                                                                                                                        notify: null | Characteristic;
                                                                                                                                                                                                                                                                                                                        write: null | Characteristic;
                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                    device: null | Characteristic
                                                                                                                                                                                                                                                                                                                    notify: null | Characteristic
                                                                                                                                                                                                                                                                                                                    write: null | Characteristic
                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/ColorLightServiceDataBase.html b/docs/interfaces/ColorLightServiceDataBase.html deleted file mode 100644 index 91d96fd9..00000000 --- a/docs/interfaces/ColorLightServiceDataBase.html +++ /dev/null @@ -1,17 +0,0 @@ -ColorLightServiceDataBase | node-switchbot
                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                      Interface ColorLightServiceDataBase

                                                                                                                                                                                                                                                                                                                      Base interface for color-controllable devices.

                                                                                                                                                                                                                                                                                                                      -
                                                                                                                                                                                                                                                                                                                      interface ColorLightServiceDataBase {
                                                                                                                                                                                                                                                                                                                          blue: number;
                                                                                                                                                                                                                                                                                                                          brightness: number;
                                                                                                                                                                                                                                                                                                                          color_mode: number;
                                                                                                                                                                                                                                                                                                                          color_temperature: number;
                                                                                                                                                                                                                                                                                                                          delay: number;
                                                                                                                                                                                                                                                                                                                          green: number;
                                                                                                                                                                                                                                                                                                                          loop_index: number;
                                                                                                                                                                                                                                                                                                                          model: SwitchBotBLEModel;
                                                                                                                                                                                                                                                                                                                          modelFriendlyName: SwitchBotBLEModelFriendlyName;
                                                                                                                                                                                                                                                                                                                          modelName: SwitchBotBLEModelName;
                                                                                                                                                                                                                                                                                                                          power: boolean;
                                                                                                                                                                                                                                                                                                                          preset: number;
                                                                                                                                                                                                                                                                                                                          red: number;
                                                                                                                                                                                                                                                                                                                          speed: number;
                                                                                                                                                                                                                                                                                                                          state: boolean;
                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                      Hierarchy

                                                                                                                                                                                                                                                                                                                      • BLEServiceData
                                                                                                                                                                                                                                                                                                                        • ColorLightServiceDataBase
                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                      blue: number
                                                                                                                                                                                                                                                                                                                      brightness: number
                                                                                                                                                                                                                                                                                                                      color_mode: number
                                                                                                                                                                                                                                                                                                                      color_temperature: number
                                                                                                                                                                                                                                                                                                                      delay: number
                                                                                                                                                                                                                                                                                                                      green: number
                                                                                                                                                                                                                                                                                                                      loop_index: number
                                                                                                                                                                                                                                                                                                                      power: boolean
                                                                                                                                                                                                                                                                                                                      preset: number
                                                                                                                                                                                                                                                                                                                      red: number
                                                                                                                                                                                                                                                                                                                      speed: number
                                                                                                                                                                                                                                                                                                                      state: boolean
                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/CommandResult.html b/docs/interfaces/CommandResult.html new file mode 100644 index 00000000..5c4bc204 --- /dev/null +++ b/docs/interfaces/CommandResult.html @@ -0,0 +1,12 @@ +CommandResult | node-switchbot
                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                        Interface CommandResult

                                                                                                                                                                                                                                                                                                                        Device command result

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        interface CommandResult {
                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                            data?: any;
                                                                                                                                                                                                                                                                                                                            error?: string;
                                                                                                                                                                                                                                                                                                                            success: boolean;
                                                                                                                                                                                                                                                                                                                            usedFallback?: boolean;
                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                        Connection type used

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        data?: any

                                                                                                                                                                                                                                                                                                                        Response data

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        error?: string

                                                                                                                                                                                                                                                                                                                        Error message (if failed)

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        success: boolean

                                                                                                                                                                                                                                                                                                                        Success status

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        usedFallback?: boolean

                                                                                                                                                                                                                                                                                                                        Whether API fallback was used

                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/ContactServiceData.html b/docs/interfaces/ContactServiceData.html new file mode 100644 index 00000000..bdb1dc9f --- /dev/null +++ b/docs/interfaces/ContactServiceData.html @@ -0,0 +1,30 @@ +ContactServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                          Interface ContactServiceData

                                                                                                                                                                                                                                                                                                                          Contact Sensor BLE Service Data

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          interface ContactServiceData {
                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                              lightLevel: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                                                              movement: boolean;
                                                                                                                                                                                                                                                                                                                              position: "closed" | "open" | "timeout";
                                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                              state?: boolean;
                                                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                          battery: number

                                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          lightLevel: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          movement: boolean
                                                                                                                                                                                                                                                                                                                          position: "closed" | "open" | "timeout"
                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          state?: boolean

                                                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/ContactStatus.html b/docs/interfaces/ContactStatus.html new file mode 100644 index 00000000..c13f0005 --- /dev/null +++ b/docs/interfaces/ContactStatus.html @@ -0,0 +1,15 @@ +ContactStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                            Interface ContactStatus

                                                                                                                                                                                                                                                                                                                            Contact Sensor specific types

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            interface ContactStatus {
                                                                                                                                                                                                                                                                                                                                battery?: number;
                                                                                                                                                                                                                                                                                                                                brightness?: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                deviceId: string;
                                                                                                                                                                                                                                                                                                                                moveDetected?: boolean;
                                                                                                                                                                                                                                                                                                                                openState: "closed" | "open" | "timeout";
                                                                                                                                                                                                                                                                                                                                updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                version?: string;
                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                            battery?: number

                                                                                                                                                                                                                                                                                                                            Battery level (0-100)

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            brightness?: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                            Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            deviceId: string

                                                                                                                                                                                                                                                                                                                            Device ID

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            moveDetected?: boolean
                                                                                                                                                                                                                                                                                                                            openState: "closed" | "open" | "timeout"
                                                                                                                                                                                                                                                                                                                            updatedAt?: Date

                                                                                                                                                                                                                                                                                                                            Last updated timestamp

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            version?: string

                                                                                                                                                                                                                                                                                                                            Firmware version

                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/CurtainCommands.html b/docs/interfaces/CurtainCommands.html new file mode 100644 index 00000000..ae549e5f --- /dev/null +++ b/docs/interfaces/CurtainCommands.html @@ -0,0 +1,8 @@ +CurtainCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                              Interface CurtainCommands

                                                                                                                                                                                                                                                                                                                              interface CurtainCommands {
                                                                                                                                                                                                                                                                                                                                  close: (speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                  getExtendedInfo?: () => Promise<CurtainExtendedInfo>;
                                                                                                                                                                                                                                                                                                                                  open: (speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                  pause: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                  sendCommandSequence?: (
                                                                                                                                                                                                                                                                                                                                      commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                                  ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                  sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                                      commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                                  ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                  setPosition: (position: number, speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                                              Implemented by

                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                              close: (speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              getExtendedInfo?: () => Promise<CurtainExtendedInfo>
                                                                                                                                                                                                                                                                                                                              open: (speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              pause: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              sendCommandSequence?: (commands: (() => Promise<boolean>)[]) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                                  commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                              ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              setPosition: (position: number, speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/CurtainExtendedInfo.html b/docs/interfaces/CurtainExtendedInfo.html new file mode 100644 index 00000000..21b34c80 --- /dev/null +++ b/docs/interfaces/CurtainExtendedInfo.html @@ -0,0 +1,4 @@ +CurtainExtendedInfo | node-switchbot
                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                Interface CurtainExtendedInfo

                                                                                                                                                                                                                                                                                                                                Curtain extended info (device chain, grouped status)

                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                interface CurtainExtendedInfo {
                                                                                                                                                                                                                                                                                                                                    deviceChain?: { masterDevice: string; slaveDevices: string[] };
                                                                                                                                                                                                                                                                                                                                    groupStatus?: { calibrated: boolean; moving: boolean; position: number };
                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                deviceChain?: { masterDevice: string; slaveDevices: string[] }
                                                                                                                                                                                                                                                                                                                                groupStatus?: { calibrated: boolean; moving: boolean; position: number }
                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/CurtainServiceData.html b/docs/interfaces/CurtainServiceData.html new file mode 100644 index 00000000..19aeb642 --- /dev/null +++ b/docs/interfaces/CurtainServiceData.html @@ -0,0 +1,31 @@ +CurtainServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                  Interface CurtainServiceData

                                                                                                                                                                                                                                                                                                                                  Curtain BLE Service Data

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  interface CurtainServiceData {
                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                      calibration: boolean;
                                                                                                                                                                                                                                                                                                                                      channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                      deviceChain?: number;
                                                                                                                                                                                                                                                                                                                                      doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                      inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                      lightLevel: number;
                                                                                                                                                                                                                                                                                                                                      lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                      model: string;
                                                                                                                                                                                                                                                                                                                                      modelName: string;
                                                                                                                                                                                                                                                                                                                                      position: number;
                                                                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                      sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                      state?: boolean;
                                                                                                                                                                                                                                                                                                                                      status?: number;
                                                                                                                                                                                                                                                                                                                                      [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                  Indexable

                                                                                                                                                                                                                                                                                                                                  • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                    Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                  battery: number

                                                                                                                                                                                                                                                                                                                                  Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  calibration: boolean
                                                                                                                                                                                                                                                                                                                                  channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                  Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  deviceChain?: number
                                                                                                                                                                                                                                                                                                                                  doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                  Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                  Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  lightLevel: number
                                                                                                                                                                                                                                                                                                                                  lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                  Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                  Parsed mode where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  model: string

                                                                                                                                                                                                                                                                                                                                  Device model

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  modelName: string

                                                                                                                                                                                                                                                                                                                                  Model name string

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  position: number
                                                                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                  Raw service data buffer

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                  Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  state?: boolean

                                                                                                                                                                                                                                                                                                                                  Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  status?: number

                                                                                                                                                                                                                                                                                                                                  Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/CurtainStatus.html b/docs/interfaces/CurtainStatus.html new file mode 100644 index 00000000..9d43c222 --- /dev/null +++ b/docs/interfaces/CurtainStatus.html @@ -0,0 +1,17 @@ +CurtainStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                    Interface CurtainStatus

                                                                                                                                                                                                                                                                                                                                    Curtain (WoCurtain) specific types

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    interface CurtainStatus {
                                                                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                                                                        calibrated?: boolean;
                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                        deviceId: string;
                                                                                                                                                                                                                                                                                                                                        direction?: "opening" | "closing";
                                                                                                                                                                                                                                                                                                                                        moving?: boolean;
                                                                                                                                                                                                                                                                                                                                        position: number;
                                                                                                                                                                                                                                                                                                                                        slidePosition?: number;
                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                        version?: string;
                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    calibrated?: boolean
                                                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                    Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    deviceId: string

                                                                                                                                                                                                                                                                                                                                    Device ID

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    direction?: "opening" | "closing"
                                                                                                                                                                                                                                                                                                                                    moving?: boolean
                                                                                                                                                                                                                                                                                                                                    position: number
                                                                                                                                                                                                                                                                                                                                    slidePosition?: number
                                                                                                                                                                                                                                                                                                                                    updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                    Last updated timestamp

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    version?: string

                                                                                                                                                                                                                                                                                                                                    Firmware version

                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/DeviceInfo.html b/docs/interfaces/DeviceInfo.html new file mode 100644 index 00000000..1c6b02d1 --- /dev/null +++ b/docs/interfaces/DeviceInfo.html @@ -0,0 +1,36 @@ +DeviceInfo | node-switchbot
                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                      Interface DeviceInfo

                                                                                                                                                                                                                                                                                                                                      Base device information

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      interface DeviceInfo {
                                                                                                                                                                                                                                                                                                                                          activeConnection?: ConnectionType;
                                                                                                                                                                                                                                                                                                                                          battery?: number;
                                                                                                                                                                                                                                                                                                                                          bleId?: string;
                                                                                                                                                                                                                                                                                                                                          bleServiceData?: Record<string, unknown>;
                                                                                                                                                                                                                                                                                                                                          cloudServiceEnabled?: boolean;
                                                                                                                                                                                                                                                                                                                                          connectionTypes: ConnectionType[];
                                                                                                                                                                                                                                                                                                                                          deviceType: string;
                                                                                                                                                                                                                                                                                                                                          encryptionIV?: string;
                                                                                                                                                                                                                                                                                                                                          encryptionKey?: string;
                                                                                                                                                                                                                                                                                                                                          encryptionMode?: "auto" | "ctr" | "gcm";
                                                                                                                                                                                                                                                                                                                                          hubDeviceId?: string;
                                                                                                                                                                                                                                                                                                                                          id: string;
                                                                                                                                                                                                                                                                                                                                          mac?: string;
                                                                                                                                                                                                                                                                                                                                          model?: string;
                                                                                                                                                                                                                                                                                                                                          name: string;
                                                                                                                                                                                                                                                                                                                                          rssi?: number;
                                                                                                                                                                                                                                                                                                                                          version?: string;
                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                      activeConnection?: ConnectionType

                                                                                                                                                                                                                                                                                                                                      Current active connection type

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      battery?: number

                                                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      bleId?: string

                                                                                                                                                                                                                                                                                                                                      BLE peripheral/advertisement ID (for ID-based lookups on macOS)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      bleServiceData?: Record<string, unknown>

                                                                                                                                                                                                                                                                                                                                      Last parsed BLE advertisement service data

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      cloudServiceEnabled?: boolean

                                                                                                                                                                                                                                                                                                                                      CloudService enabled in OpenAPI

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      connectionTypes: ConnectionType[]

                                                                                                                                                                                                                                                                                                                                      Available connection types

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      deviceType: string

                                                                                                                                                                                                                                                                                                                                      Device type (e.g., 'Bot', 'Curtain', 'Lock')

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      encryptionIV?: string

                                                                                                                                                                                                                                                                                                                                      Optional BLE encryption IV as hex

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      encryptionKey?: string

                                                                                                                                                                                                                                                                                                                                      Optional BLE encryption key as hex (16 bytes / 32 hex chars)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      encryptionMode?: "auto" | "ctr" | "gcm"

                                                                                                                                                                                                                                                                                                                                      Optional BLE encryption mode

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      hubDeviceId?: string

                                                                                                                                                                                                                                                                                                                                      Hub device ID (if device is controlled through a hub)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      id: string

                                                                                                                                                                                                                                                                                                                                      Device ID

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      mac?: string

                                                                                                                                                                                                                                                                                                                                      MAC address (for BLE devices)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      model?: string

                                                                                                                                                                                                                                                                                                                                      Device model

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      name: string

                                                                                                                                                                                                                                                                                                                                      Device name

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      rssi?: number

                                                                                                                                                                                                                                                                                                                                      RSSI signal strength (for BLE)

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      version?: string

                                                                                                                                                                                                                                                                                                                                      Firmware version

                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/DeviceListResponse.html b/docs/interfaces/DeviceListResponse.html new file mode 100644 index 00000000..6c0769e0 --- /dev/null +++ b/docs/interfaces/DeviceListResponse.html @@ -0,0 +1,4 @@ +DeviceListResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                        Interface DeviceListResponse

                                                                                                                                                                                                                                                                                                                                        Device list response from OpenAPI

                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                        interface DeviceListResponse {
                                                                                                                                                                                                                                                                                                                                            deviceList: APIDevice[];
                                                                                                                                                                                                                                                                                                                                            infraredRemoteList?: APIInfraredRemote[];
                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                        deviceList: APIDevice[]
                                                                                                                                                                                                                                                                                                                                        infraredRemoteList?: APIInfraredRemote[]
                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/DiscoveryOptions.html b/docs/interfaces/DiscoveryOptions.html new file mode 100644 index 00000000..b1816238 --- /dev/null +++ b/docs/interfaces/DiscoveryOptions.html @@ -0,0 +1,14 @@ +DiscoveryOptions | node-switchbot
                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                          Interface DiscoveryOptions

                                                                                                                                                                                                                                                                                                                                          Device discovery options

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          interface DiscoveryOptions {
                                                                                                                                                                                                                                                                                                                                              deviceId?: string;
                                                                                                                                                                                                                                                                                                                                              deviceType?: string;
                                                                                                                                                                                                                                                                                                                                              fetchAPI?: boolean;
                                                                                                                                                                                                                                                                                                                                              mac?: string;
                                                                                                                                                                                                                                                                                                                                              scanBLE?: boolean;
                                                                                                                                                                                                                                                                                                                                              timeout?: number;
                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                          deviceId?: string

                                                                                                                                                                                                                                                                                                                                          Filter by device ID (optional)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          deviceType?: string

                                                                                                                                                                                                                                                                                                                                          Filter by device type (optional)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          fetchAPI?: boolean

                                                                                                                                                                                                                                                                                                                                          Fetch devices from API (default: true if credentials provided)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          mac?: string

                                                                                                                                                                                                                                                                                                                                          Filter by device MAC address (optional)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          scanBLE?: boolean

                                                                                                                                                                                                                                                                                                                                          Scan for BLE devices (default: true if BLE enabled)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          timeout?: number

                                                                                                                                                                                                                                                                                                                                          Discovery timeout in milliseconds (default: 10000)

                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/ErrorObject.html b/docs/interfaces/ErrorObject.html deleted file mode 100644 index d6d3da99..00000000 --- a/docs/interfaces/ErrorObject.html +++ /dev/null @@ -1,3 +0,0 @@ -ErrorObject | node-switchbot
                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                            Interface ErrorObject

                                                                                                                                                                                                                                                                                                                                            interface ErrorObject {
                                                                                                                                                                                                                                                                                                                                                code: string;
                                                                                                                                                                                                                                                                                                                                                message: string;
                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                            code: string
                                                                                                                                                                                                                                                                                                                                            message: string
                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/HubServiceData.html b/docs/interfaces/HubServiceData.html new file mode 100644 index 00000000..317dfcd3 --- /dev/null +++ b/docs/interfaces/HubServiceData.html @@ -0,0 +1,31 @@ +HubServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                              Interface HubServiceData

                                                                                                                                                                                                                                                                                                                                              Hub BLE Service Data

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              interface HubServiceData {
                                                                                                                                                                                                                                                                                                                                                  battery?: number;
                                                                                                                                                                                                                                                                                                                                                  channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                  doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                  fahrenheit: boolean;
                                                                                                                                                                                                                                                                                                                                                  humidity: number;
                                                                                                                                                                                                                                                                                                                                                  inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                  lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                  lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                  mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                  model: string;
                                                                                                                                                                                                                                                                                                                                                  modelName: string;
                                                                                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                  sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                  state?: boolean;
                                                                                                                                                                                                                                                                                                                                                  status?: number;
                                                                                                                                                                                                                                                                                                                                                  temperature: number;
                                                                                                                                                                                                                                                                                                                                                  [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                              Indexable

                                                                                                                                                                                                                                                                                                                                              • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                              battery?: number

                                                                                                                                                                                                                                                                                                                                              Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                              Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                              Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              fahrenheit: boolean
                                                                                                                                                                                                                                                                                                                                              humidity: number
                                                                                                                                                                                                                                                                                                                                              inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                              Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              lightLevel: number
                                                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                              Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                              Parsed mode where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              model: string

                                                                                                                                                                                                                                                                                                                                              Device model

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              modelName: string

                                                                                                                                                                                                                                                                                                                                              Model name string

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                              Raw service data buffer

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                              Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              state?: boolean

                                                                                                                                                                                                                                                                                                                                              Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              status?: number

                                                                                                                                                                                                                                                                                                                                              Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                              temperature: number
                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/HubStatus.html b/docs/interfaces/HubStatus.html new file mode 100644 index 00000000..f4e23f1d --- /dev/null +++ b/docs/interfaces/HubStatus.html @@ -0,0 +1,15 @@ +HubStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                Interface HubStatus

                                                                                                                                                                                                                                                                                                                                                Hub specific types

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                interface HubStatus {
                                                                                                                                                                                                                                                                                                                                                    battery?: number;
                                                                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                    deviceId: string;
                                                                                                                                                                                                                                                                                                                                                    humidity?: number;
                                                                                                                                                                                                                                                                                                                                                    lightLevel?: number;
                                                                                                                                                                                                                                                                                                                                                    temperature?: number;
                                                                                                                                                                                                                                                                                                                                                    updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                    version?: string;
                                                                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                battery?: number

                                                                                                                                                                                                                                                                                                                                                Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                deviceId: string

                                                                                                                                                                                                                                                                                                                                                Device ID

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                humidity?: number
                                                                                                                                                                                                                                                                                                                                                lightLevel?: number
                                                                                                                                                                                                                                                                                                                                                temperature?: number
                                                                                                                                                                                                                                                                                                                                                updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                version?: string

                                                                                                                                                                                                                                                                                                                                                Firmware version

                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/HumidifierCommands.html b/docs/interfaces/HumidifierCommands.html new file mode 100644 index 00000000..a0287777 --- /dev/null +++ b/docs/interfaces/HumidifierCommands.html @@ -0,0 +1,9 @@ +HumidifierCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                  Interface HumidifierCommands

                                                                                                                                                                                                                                                                                                                                                  interface HumidifierCommands {
                                                                                                                                                                                                                                                                                                                                                      getTargetLevel?: () => Promise<number | undefined>;
                                                                                                                                                                                                                                                                                                                                                      setAuto?: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                      setEfficiency: (level: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                      setLevel?: (level: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                      setManual?: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                      setMode: (mode: "auto" | "manual") => Promise<CommandResult>;
                                                                                                                                                                                                                                                                                                                                                      turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                      turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                                  Implemented by

                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                  getTargetLevel?: () => Promise<number | undefined>
                                                                                                                                                                                                                                                                                                                                                  setAuto?: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  setEfficiency: (level: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  setLevel?: (level: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  setManual?: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  setMode: (mode: "auto" | "manual") => Promise<CommandResult>
                                                                                                                                                                                                                                                                                                                                                  turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/HumidifierServiceData.html b/docs/interfaces/HumidifierServiceData.html new file mode 100644 index 00000000..33d7ca8b --- /dev/null +++ b/docs/interfaces/HumidifierServiceData.html @@ -0,0 +1,31 @@ +HumidifierServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                    Interface HumidifierServiceData

                                                                                                                                                                                                                                                                                                                                                    Humidifier BLE Service Data

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    interface HumidifierServiceData {
                                                                                                                                                                                                                                                                                                                                                        autoMode: boolean;
                                                                                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                                                                                        channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                        doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                        inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                        lackWater: boolean;
                                                                                                                                                                                                                                                                                                                                                        lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                        mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                        model: string;
                                                                                                                                                                                                                                                                                                                                                        modelName: string;
                                                                                                                                                                                                                                                                                                                                                        onState: boolean;
                                                                                                                                                                                                                                                                                                                                                        percentage: number;
                                                                                                                                                                                                                                                                                                                                                        rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                        sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                        state?: boolean;
                                                                                                                                                                                                                                                                                                                                                        status?: number;
                                                                                                                                                                                                                                                                                                                                                        [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                    Indexable

                                                                                                                                                                                                                                                                                                                                                    • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                      Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                    autoMode: boolean
                                                                                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                    Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                    Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                    Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    lackWater: boolean
                                                                                                                                                                                                                                                                                                                                                    lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                    Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                    Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    model: string

                                                                                                                                                                                                                                                                                                                                                    Device model

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    modelName: string

                                                                                                                                                                                                                                                                                                                                                    Model name string

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    onState: boolean
                                                                                                                                                                                                                                                                                                                                                    percentage: number
                                                                                                                                                                                                                                                                                                                                                    rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                    Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                    Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    state?: boolean

                                                                                                                                                                                                                                                                                                                                                    Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    status?: number

                                                                                                                                                                                                                                                                                                                                                    Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/HumidifierStatus.html b/docs/interfaces/HumidifierStatus.html new file mode 100644 index 00000000..71c00448 --- /dev/null +++ b/docs/interfaces/HumidifierStatus.html @@ -0,0 +1,18 @@ +HumidifierStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                      Interface HumidifierStatus

                                                                                                                                                                                                                                                                                                                                                      Humidifier specific types

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      interface HumidifierStatus {
                                                                                                                                                                                                                                                                                                                                                          battery?: number;
                                                                                                                                                                                                                                                                                                                                                          connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                          deviceId: string;
                                                                                                                                                                                                                                                                                                                                                          humidity?: number;
                                                                                                                                                                                                                                                                                                                                                          lackWater?: boolean;
                                                                                                                                                                                                                                                                                                                                                          mode?: "auto" | "manual";
                                                                                                                                                                                                                                                                                                                                                          nebulizationEfficiency?: number;
                                                                                                                                                                                                                                                                                                                                                          power: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                          temperature?: number;
                                                                                                                                                                                                                                                                                                                                                          updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                          version?: string;
                                                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                      battery?: number

                                                                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                      Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      deviceId: string

                                                                                                                                                                                                                                                                                                                                                      Device ID

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      humidity?: number
                                                                                                                                                                                                                                                                                                                                                      lackWater?: boolean
                                                                                                                                                                                                                                                                                                                                                      mode?: "auto" | "manual"
                                                                                                                                                                                                                                                                                                                                                      nebulizationEfficiency?: number
                                                                                                                                                                                                                                                                                                                                                      power: "on" | "off"
                                                                                                                                                                                                                                                                                                                                                      temperature?: number
                                                                                                                                                                                                                                                                                                                                                      updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                      Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      version?: string

                                                                                                                                                                                                                                                                                                                                                      Firmware version

                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/KeypadStatus.html b/docs/interfaces/KeypadStatus.html new file mode 100644 index 00000000..8671a713 --- /dev/null +++ b/docs/interfaces/KeypadStatus.html @@ -0,0 +1,13 @@ +KeypadStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                        Interface KeypadStatus

                                                                                                                                                                                                                                                                                                                                                        Keypad specific types

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        interface KeypadStatus {
                                                                                                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                                                                                                            lockState?: "locked" | "unlocked";
                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                            version?: string;
                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                        battery?: number

                                                                                                                                                                                                                                                                                                                                                        Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                        Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        deviceId: string

                                                                                                                                                                                                                                                                                                                                                        Device ID

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        lockState?: "locked" | "unlocked"
                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                        Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        version?: string

                                                                                                                                                                                                                                                                                                                                                        Firmware version

                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/LeakServiceData.html b/docs/interfaces/LeakServiceData.html new file mode 100644 index 00000000..810fef70 --- /dev/null +++ b/docs/interfaces/LeakServiceData.html @@ -0,0 +1,28 @@ +LeakServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                          Interface LeakServiceData

                                                                                                                                                                                                                                                                                                                                                          Leak Detector BLE Service Data

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          interface LeakServiceData {
                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                              state?: boolean;
                                                                                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                                                                                              waterLeakDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                          battery: number

                                                                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          state?: boolean

                                                                                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                          waterLeakDetected: boolean
                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/LeakStatus.html b/docs/interfaces/LeakStatus.html new file mode 100644 index 00000000..b75bcfb3 --- /dev/null +++ b/docs/interfaces/LeakStatus.html @@ -0,0 +1,13 @@ +LeakStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                            Interface LeakStatus

                                                                                                                                                                                                                                                                                                                                                            Leak Detector specific types

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            interface LeakStatus {
                                                                                                                                                                                                                                                                                                                                                                battery?: number;
                                                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                version?: string;
                                                                                                                                                                                                                                                                                                                                                                waterLeakDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                            battery?: number

                                                                                                                                                                                                                                                                                                                                                            Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                            Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            deviceId: string

                                                                                                                                                                                                                                                                                                                                                            Device ID

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                            Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            version?: string

                                                                                                                                                                                                                                                                                                                                                            Firmware version

                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                            waterLeakDetected: boolean
                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/LockBaseServiceData.html b/docs/interfaces/LockBaseServiceData.html deleted file mode 100644 index 92187b96..00000000 --- a/docs/interfaces/LockBaseServiceData.html +++ /dev/null @@ -1,15 +0,0 @@ -LockBaseServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                              Interface LockBaseServiceData

                                                                                                                                                                                                                                                                                                                                                              Base interface for lock-style devices.

                                                                                                                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                                                                                                                              interface LockBaseServiceData {
                                                                                                                                                                                                                                                                                                                                                                  auto_lock_paused: boolean;
                                                                                                                                                                                                                                                                                                                                                                  battery: number;
                                                                                                                                                                                                                                                                                                                                                                  calibration: boolean;
                                                                                                                                                                                                                                                                                                                                                                  door_open: boolean;
                                                                                                                                                                                                                                                                                                                                                                  double_lock_mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                  model: SwitchBotBLEModel;
                                                                                                                                                                                                                                                                                                                                                                  modelFriendlyName: SwitchBotBLEModelFriendlyName;
                                                                                                                                                                                                                                                                                                                                                                  modelName: SwitchBotBLEModelName;
                                                                                                                                                                                                                                                                                                                                                                  night_latch: boolean;
                                                                                                                                                                                                                                                                                                                                                                  status: string;
                                                                                                                                                                                                                                                                                                                                                                  unclosed_alarm: boolean;
                                                                                                                                                                                                                                                                                                                                                                  unlocked_alarm: boolean;
                                                                                                                                                                                                                                                                                                                                                                  update_from_secondary_lock: boolean;
                                                                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                                                                              Hierarchy

                                                                                                                                                                                                                                                                                                                                                              • BLEServiceData
                                                                                                                                                                                                                                                                                                                                                                • LockBaseServiceData
                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                              auto_lock_paused: boolean
                                                                                                                                                                                                                                                                                                                                                              battery: number
                                                                                                                                                                                                                                                                                                                                                              calibration: boolean
                                                                                                                                                                                                                                                                                                                                                              door_open: boolean
                                                                                                                                                                                                                                                                                                                                                              double_lock_mode: boolean
                                                                                                                                                                                                                                                                                                                                                              night_latch: boolean
                                                                                                                                                                                                                                                                                                                                                              status: string
                                                                                                                                                                                                                                                                                                                                                              unclosed_alarm: boolean
                                                                                                                                                                                                                                                                                                                                                              unlocked_alarm: boolean
                                                                                                                                                                                                                                                                                                                                                              update_from_secondary_lock: boolean
                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/LockCommands.html b/docs/interfaces/LockCommands.html new file mode 100644 index 00000000..a297435c --- /dev/null +++ b/docs/interfaces/LockCommands.html @@ -0,0 +1,7 @@ +LockCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                Interface LockCommands

                                                                                                                                                                                                                                                                                                                                                                interface LockCommands {
                                                                                                                                                                                                                                                                                                                                                                    getLockInfo?: () => Promise<Record<string, unknown>>;
                                                                                                                                                                                                                                                                                                                                                                    lock: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                    offLockNotification?: (handler: (payload: Buffer) => void) => void;
                                                                                                                                                                                                                                                                                                                                                                    onLockNotification?: (handler: (payload: Buffer) => void) => Promise<void>;
                                                                                                                                                                                                                                                                                                                                                                    unlock: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                    unlockWithoutUnlatch?: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                                                                                Implemented by

                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                getLockInfo?: () => Promise<Record<string, unknown>>
                                                                                                                                                                                                                                                                                                                                                                lock: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                offLockNotification?: (handler: (payload: Buffer) => void) => void
                                                                                                                                                                                                                                                                                                                                                                onLockNotification?: (handler: (payload: Buffer) => void) => Promise<void>
                                                                                                                                                                                                                                                                                                                                                                unlock: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                unlockWithoutUnlatch?: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/LockServiceData.html b/docs/interfaces/LockServiceData.html new file mode 100644 index 00000000..f9a2b236 --- /dev/null +++ b/docs/interfaces/LockServiceData.html @@ -0,0 +1,29 @@ +LockServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                  Interface LockServiceData

                                                                                                                                                                                                                                                                                                                                                                  Lock BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  interface LockServiceData {
                                                                                                                                                                                                                                                                                                                                                                      autoLockDelay?: number;
                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                      calibration: boolean;
                                                                                                                                                                                                                                                                                                                                                                      channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                      doorOpen: boolean;
                                                                                                                                                                                                                                                                                                                                                                      inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                      lockState: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                      model: string;
                                                                                                                                                                                                                                                                                                                                                                      modelName: string;
                                                                                                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                      sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                      state?: boolean;
                                                                                                                                                                                                                                                                                                                                                                      status: number;
                                                                                                                                                                                                                                                                                                                                                                      [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                  Indexable

                                                                                                                                                                                                                                                                                                                                                                  • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                    Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                  autoLockDelay?: number
                                                                                                                                                                                                                                                                                                                                                                  battery: number

                                                                                                                                                                                                                                                                                                                                                                  Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  calibration: boolean
                                                                                                                                                                                                                                                                                                                                                                  channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                  Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  doorOpen: boolean

                                                                                                                                                                                                                                                                                                                                                                  Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                  Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  lockState: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                  Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                  Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  model: string

                                                                                                                                                                                                                                                                                                                                                                  Device model

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  modelName: string

                                                                                                                                                                                                                                                                                                                                                                  Model name string

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                  Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                  Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  state?: boolean

                                                                                                                                                                                                                                                                                                                                                                  Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  status: number

                                                                                                                                                                                                                                                                                                                                                                  Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/LockStatus.html b/docs/interfaces/LockStatus.html new file mode 100644 index 00000000..0cf8aae4 --- /dev/null +++ b/docs/interfaces/LockStatus.html @@ -0,0 +1,15 @@ +LockStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                    Interface LockStatus

                                                                                                                                                                                                                                                                                                                                                                    Lock (WoSmartLock) specific types

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    interface LockStatus {
                                                                                                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                                                                                                        calibrated?: boolean;
                                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                        deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                        doorState?: "opened" | "closed";
                                                                                                                                                                                                                                                                                                                                                                        lockState: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                        version?: string;
                                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    calibrated?: boolean
                                                                                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                    Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    deviceId: string

                                                                                                                                                                                                                                                                                                                                                                    Device ID

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    doorState?: "opened" | "closed"
                                                                                                                                                                                                                                                                                                                                                                    lockState: "locked" | "unlocked" | "jammed"
                                                                                                                                                                                                                                                                                                                                                                    updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                    Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    version?: string

                                                                                                                                                                                                                                                                                                                                                                    Firmware version

                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/MeterServiceData.html b/docs/interfaces/MeterServiceData.html new file mode 100644 index 00000000..2794f814 --- /dev/null +++ b/docs/interfaces/MeterServiceData.html @@ -0,0 +1,30 @@ +MeterServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                      Interface MeterServiceData

                                                                                                                                                                                                                                                                                                                                                                      Meter BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      interface MeterServiceData {
                                                                                                                                                                                                                                                                                                                                                                          battery: number;
                                                                                                                                                                                                                                                                                                                                                                          channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                          fahrenheit: boolean;
                                                                                                                                                                                                                                                                                                                                                                          humidity: number;
                                                                                                                                                                                                                                                                                                                                                                          inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                          model: string;
                                                                                                                                                                                                                                                                                                                                                                          modelName: string;
                                                                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                          state?: boolean;
                                                                                                                                                                                                                                                                                                                                                                          status?: number;
                                                                                                                                                                                                                                                                                                                                                                          temperature: number;
                                                                                                                                                                                                                                                                                                                                                                          [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                      Indexable

                                                                                                                                                                                                                                                                                                                                                                      • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                        Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                      battery: number

                                                                                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                      Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                      Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      fahrenheit: boolean
                                                                                                                                                                                                                                                                                                                                                                      humidity: number
                                                                                                                                                                                                                                                                                                                                                                      inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                      Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                      Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                      Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      model: string

                                                                                                                                                                                                                                                                                                                                                                      Device model

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      modelName: string

                                                                                                                                                                                                                                                                                                                                                                      Model name string

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                      Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                      Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      state?: boolean

                                                                                                                                                                                                                                                                                                                                                                      Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      status?: number

                                                                                                                                                                                                                                                                                                                                                                      Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                      temperature: number
                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/MeterStatus.html b/docs/interfaces/MeterStatus.html new file mode 100644 index 00000000..5b57879e --- /dev/null +++ b/docs/interfaces/MeterStatus.html @@ -0,0 +1,15 @@ +MeterStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                        Interface MeterStatus

                                                                                                                                                                                                                                                                                                                                                                        Meter (Temperature/Humidity) specific types

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        interface MeterStatus {
                                                                                                                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                            humidity: number;
                                                                                                                                                                                                                                                                                                                                                                            temperature: number;
                                                                                                                                                                                                                                                                                                                                                                            temperatureScale?: "c" | "f";
                                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                            version?: string;
                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                        battery?: number

                                                                                                                                                                                                                                                                                                                                                                        Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                        Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        deviceId: string

                                                                                                                                                                                                                                                                                                                                                                        Device ID

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        humidity: number
                                                                                                                                                                                                                                                                                                                                                                        temperature: number
                                                                                                                                                                                                                                                                                                                                                                        temperatureScale?: "c" | "f"
                                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                        Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        version?: string

                                                                                                                                                                                                                                                                                                                                                                        Firmware version

                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/MotionServiceData.html b/docs/interfaces/MotionServiceData.html new file mode 100644 index 00000000..ec49a552 --- /dev/null +++ b/docs/interfaces/MotionServiceData.html @@ -0,0 +1,30 @@ +MotionServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                          Interface MotionServiceData

                                                                                                                                                                                                                                                                                                                                                                          Motion Sensor BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          interface MotionServiceData {
                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                              iotButton?: boolean;
                                                                                                                                                                                                                                                                                                                                                                              lightLevel: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                                                                                                              movement: boolean;
                                                                                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                              state?: boolean;
                                                                                                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                          battery: number

                                                                                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          iotButton?: boolean
                                                                                                                                                                                                                                                                                                                                                                          lightLevel: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          movement: boolean
                                                                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          state?: boolean

                                                                                                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/MotionStatus.html b/docs/interfaces/MotionStatus.html new file mode 100644 index 00000000..745fb762 --- /dev/null +++ b/docs/interfaces/MotionStatus.html @@ -0,0 +1,14 @@ +MotionStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                            Interface MotionStatus

                                                                                                                                                                                                                                                                                                                                                                            Motion Sensor specific types

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            interface MotionStatus {
                                                                                                                                                                                                                                                                                                                                                                                battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                brightness?: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                version?: string;
                                                                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                            battery?: number

                                                                                                                                                                                                                                                                                                                                                                            Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            brightness?: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                            Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            deviceId: string

                                                                                                                                                                                                                                                                                                                                                                            Device ID

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            moveDetected: boolean
                                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                            Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            version?: string

                                                                                                                                                                                                                                                                                                                                                                            Firmware version

                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/NobleTypes.html b/docs/interfaces/NobleTypes.html deleted file mode 100644 index 9ca16371..00000000 --- a/docs/interfaces/NobleTypes.html +++ /dev/null @@ -1,3 +0,0 @@ -NobleTypes | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                              Interface NobleTypes

                                                                                                                                                                                                                                                                                                                                                                              interface NobleTypes {
                                                                                                                                                                                                                                                                                                                                                                                  noble: Noble;
                                                                                                                                                                                                                                                                                                                                                                                  peripheral: Peripheral;
                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                              noble: Noble
                                                                                                                                                                                                                                                                                                                                                                              peripheral: Peripheral
                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/Params.html b/docs/interfaces/Params.html deleted file mode 100644 index aadb5865..00000000 --- a/docs/interfaces/Params.html +++ /dev/null @@ -1,6 +0,0 @@ -Params | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                Interface Params

                                                                                                                                                                                                                                                                                                                                                                                interface Params {
                                                                                                                                                                                                                                                                                                                                                                                    duration?: number;
                                                                                                                                                                                                                                                                                                                                                                                    id?: string;
                                                                                                                                                                                                                                                                                                                                                                                    model?: string;
                                                                                                                                                                                                                                                                                                                                                                                    noble?: Noble;
                                                                                                                                                                                                                                                                                                                                                                                    quick?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                duration?: number
                                                                                                                                                                                                                                                                                                                                                                                id?: string
                                                                                                                                                                                                                                                                                                                                                                                model?: string
                                                                                                                                                                                                                                                                                                                                                                                noble?: Noble
                                                                                                                                                                                                                                                                                                                                                                                quick?: boolean
                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/PlugCommands.html b/docs/interfaces/PlugCommands.html new file mode 100644 index 00000000..87de50f3 --- /dev/null +++ b/docs/interfaces/PlugCommands.html @@ -0,0 +1,4 @@ +PlugCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                  Interface PlugCommands

                                                                                                                                                                                                                                                                                                                                                                                  interface PlugCommands {
                                                                                                                                                                                                                                                                                                                                                                                      toggle: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                      turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                      turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                                                                  Implemented by

                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                  toggle: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                  turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                  turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/PlugMiniServiceDataBase.html b/docs/interfaces/PlugMiniServiceDataBase.html deleted file mode 100644 index d8ac10f7..00000000 --- a/docs/interfaces/PlugMiniServiceDataBase.html +++ /dev/null @@ -1,12 +0,0 @@ -PlugMiniServiceDataBase | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                    Interface PlugMiniServiceDataBase

                                                                                                                                                                                                                                                                                                                                                                                    Base interface for mini plug devices (US/JP share same schema).

                                                                                                                                                                                                                                                                                                                                                                                    -
                                                                                                                                                                                                                                                                                                                                                                                    interface PlugMiniServiceDataBase {
                                                                                                                                                                                                                                                                                                                                                                                        currentPower: number;
                                                                                                                                                                                                                                                                                                                                                                                        delay: boolean;
                                                                                                                                                                                                                                                                                                                                                                                        model: SwitchBotBLEModel;
                                                                                                                                                                                                                                                                                                                                                                                        modelFriendlyName: SwitchBotBLEModelFriendlyName;
                                                                                                                                                                                                                                                                                                                                                                                        modelName: SwitchBotBLEModelName;
                                                                                                                                                                                                                                                                                                                                                                                        overload: boolean;
                                                                                                                                                                                                                                                                                                                                                                                        state: string;
                                                                                                                                                                                                                                                                                                                                                                                        syncUtcTime: boolean;
                                                                                                                                                                                                                                                                                                                                                                                        timer: boolean;
                                                                                                                                                                                                                                                                                                                                                                                        wifiRssi: number;
                                                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                                                    Hierarchy

                                                                                                                                                                                                                                                                                                                                                                                    • BLEServiceData
                                                                                                                                                                                                                                                                                                                                                                                      • PlugMiniServiceDataBase
                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                    currentPower: number
                                                                                                                                                                                                                                                                                                                                                                                    delay: boolean
                                                                                                                                                                                                                                                                                                                                                                                    overload: boolean
                                                                                                                                                                                                                                                                                                                                                                                    state: string
                                                                                                                                                                                                                                                                                                                                                                                    syncUtcTime: boolean
                                                                                                                                                                                                                                                                                                                                                                                    timer: boolean
                                                                                                                                                                                                                                                                                                                                                                                    wifiRssi: number
                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/PlugServiceData.html b/docs/interfaces/PlugServiceData.html new file mode 100644 index 00000000..32e30fda --- /dev/null +++ b/docs/interfaces/PlugServiceData.html @@ -0,0 +1,33 @@ +PlugServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                      Interface PlugServiceData

                                                                                                                                                                                                                                                                                                                                                                                      Plug BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      interface PlugServiceData {
                                                                                                                                                                                                                                                                                                                                                                                          battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                          channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          currentPower: number;
                                                                                                                                                                                                                                                                                                                                                                                          delay: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                                          model: string;
                                                                                                                                                                                                                                                                                                                                                                                          modelName: string;
                                                                                                                                                                                                                                                                                                                                                                                          overload: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                                          state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          status?: number;
                                                                                                                                                                                                                                                                                                                                                                                          syncUtcTime: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          timer: boolean;
                                                                                                                                                                                                                                                                                                                                                                                          wifiRssi: number;
                                                                                                                                                                                                                                                                                                                                                                                          [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                      Indexable

                                                                                                                                                                                                                                                                                                                                                                                      • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                                        Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                      battery?: number

                                                                                                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                                      Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      currentPower: number
                                                                                                                                                                                                                                                                                                                                                                                      delay: boolean
                                                                                                                                                                                                                                                                                                                                                                                      doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                                      Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                                      Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                                      Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                                      Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      model: string

                                                                                                                                                                                                                                                                                                                                                                                      Device model

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      modelName: string

                                                                                                                                                                                                                                                                                                                                                                                      Model name string

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      overload: boolean
                                                                                                                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                                      Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                                      Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      state: boolean

                                                                                                                                                                                                                                                                                                                                                                                      Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      status?: number

                                                                                                                                                                                                                                                                                                                                                                                      Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                      syncUtcTime: boolean
                                                                                                                                                                                                                                                                                                                                                                                      timer: boolean
                                                                                                                                                                                                                                                                                                                                                                                      wifiRssi: number
                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/PlugStatus.html b/docs/interfaces/PlugStatus.html new file mode 100644 index 00000000..1a6dcb8b --- /dev/null +++ b/docs/interfaces/PlugStatus.html @@ -0,0 +1,16 @@ +PlugStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                        Interface PlugStatus

                                                                                                                                                                                                                                                                                                                                                                                        Plug specific types

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        interface PlugStatus {
                                                                                                                                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                            electricCurrent?: number;
                                                                                                                                                                                                                                                                                                                                                                                            electricityOfDay?: number;
                                                                                                                                                                                                                                                                                                                                                                                            power: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                            version?: string;
                                                                                                                                                                                                                                                                                                                                                                                            voltage?: number;
                                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                        battery?: number

                                                                                                                                                                                                                                                                                                                                                                                        Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                        Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                        Device ID

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        electricCurrent?: number
                                                                                                                                                                                                                                                                                                                                                                                        electricityOfDay?: number
                                                                                                                                                                                                                                                                                                                                                                                        power: "on" | "off"
                                                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                        Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        version?: string

                                                                                                                                                                                                                                                                                                                                                                                        Firmware version

                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                        voltage?: number
                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/PresenceServiceData.html b/docs/interfaces/PresenceServiceData.html new file mode 100644 index 00000000..4ad97025 --- /dev/null +++ b/docs/interfaces/PresenceServiceData.html @@ -0,0 +1,29 @@ +PresenceServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                          Interface PresenceServiceData

                                                                                                                                                                                                                                                                                                                                                                                          Presence Sensor BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          interface PresenceServiceData {
                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                              channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                              doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                              inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                              lightLevel: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                                                                                              lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                                              mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                                              model: string;
                                                                                                                                                                                                                                                                                                                                                                                              modelName: string;
                                                                                                                                                                                                                                                                                                                                                                                              movement: boolean;
                                                                                                                                                                                                                                                                                                                                                                                              rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                                              sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                                              state?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                              status?: number;
                                                                                                                                                                                                                                                                                                                                                                                              [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                          Indexable

                                                                                                                                                                                                                                                                                                                                                                                          • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                                            Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                          battery: number

                                                                                                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                                          Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                                          Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                                          Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          lightLevel: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                                                                                          lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                                          Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                                          Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          model: string

                                                                                                                                                                                                                                                                                                                                                                                          Device model

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          modelName: string

                                                                                                                                                                                                                                                                                                                                                                                          Model name string

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          movement: boolean
                                                                                                                                                                                                                                                                                                                                                                                          rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                                          Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                                          Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          state?: boolean

                                                                                                                                                                                                                                                                                                                                                                                          Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          status?: number

                                                                                                                                                                                                                                                                                                                                                                                          Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/PresenceStatus.html b/docs/interfaces/PresenceStatus.html new file mode 100644 index 00000000..120944c5 --- /dev/null +++ b/docs/interfaces/PresenceStatus.html @@ -0,0 +1,14 @@ +PresenceStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                            Interface PresenceStatus

                                                                                                                                                                                                                                                                                                                                                                                            Presence Sensor specific types

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            interface PresenceStatus {
                                                                                                                                                                                                                                                                                                                                                                                                battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                brightness?: "bright" | "dim" | "dark";
                                                                                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                version?: string;
                                                                                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                                                                                            Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                            battery?: number

                                                                                                                                                                                                                                                                                                                                                                                            Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            brightness?: "bright" | "dim" | "dark"
                                                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                            Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                            Device ID

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            moveDetected: boolean
                                                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                            Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            version?: string

                                                                                                                                                                                                                                                                                                                                                                                            Firmware version

                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/PushRequest.html b/docs/interfaces/PushRequest.html deleted file mode 100644 index 02061492..00000000 --- a/docs/interfaces/PushRequest.html +++ /dev/null @@ -1,5 +0,0 @@ -pushRequest | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                              Interface pushRequest

                                                                                                                                                                                                                                                                                                                                                                                              Request payload for controlling a device.

                                                                                                                                                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                                                                                                                                                              interface pushRequest {
                                                                                                                                                                                                                                                                                                                                                                                                  command: string;
                                                                                                                                                                                                                                                                                                                                                                                                  commandType: commandType;
                                                                                                                                                                                                                                                                                                                                                                                                  parameter: string;
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                              command: string
                                                                                                                                                                                                                                                                                                                                                                                              commandType: commandType
                                                                                                                                                                                                                                                                                                                                                                                              parameter: string
                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/PushResponseBody.html b/docs/interfaces/PushResponseBody.html deleted file mode 100644 index bf8d3f8b..00000000 --- a/docs/interfaces/PushResponseBody.html +++ /dev/null @@ -1,3 +0,0 @@ -pushResponseBody | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                Interface pushResponseBody

                                                                                                                                                                                                                                                                                                                                                                                                Body of a device push response.

                                                                                                                                                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                                                                                                                                                interface pushResponseBody {
                                                                                                                                                                                                                                                                                                                                                                                                    commandId: string;
                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                commandId: string
                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/RelaySwitchCommands.html b/docs/interfaces/RelaySwitchCommands.html new file mode 100644 index 00000000..7e9aa4df --- /dev/null +++ b/docs/interfaces/RelaySwitchCommands.html @@ -0,0 +1,6 @@ +RelaySwitchCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                  Interface RelaySwitchCommands

                                                                                                                                                                                                                                                                                                                                                                                                  interface RelaySwitchCommands {
                                                                                                                                                                                                                                                                                                                                                                                                      getCurrentTimeAndStartTime?: () => Promise<
                                                                                                                                                                                                                                                                                                                                                                                                          { currentTime: Date; startTime: Date; [key: string]: any },
                                                                                                                                                                                                                                                                                                                                                                                                      >;
                                                                                                                                                                                                                                                                                                                                                                                                      toggle: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                      turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                      turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                                                                                  Implemented by

                                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                  getCurrentTimeAndStartTime?: () => Promise<
                                                                                                                                                                                                                                                                                                                                                                                                      { currentTime: Date; startTime: Date; [key: string]: any },
                                                                                                                                                                                                                                                                                                                                                                                                  >

                                                                                                                                                                                                                                                                                                                                                                                                  Get current time and start time for energy tracking (Task 5.4)

                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                  toggle: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                  turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                  turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/RelaySwitchServiceData.html b/docs/interfaces/RelaySwitchServiceData.html new file mode 100644 index 00000000..64ca00e7 --- /dev/null +++ b/docs/interfaces/RelaySwitchServiceData.html @@ -0,0 +1,30 @@ +RelaySwitchServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                    Interface RelaySwitchServiceData

                                                                                                                                                                                                                                                                                                                                                                                                    Relay Switch BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    interface RelaySwitchServiceData {
                                                                                                                                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                        current?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                        inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                        lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                                                        mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                                                        model: string;
                                                                                                                                                                                                                                                                                                                                                                                                        modelName: string;
                                                                                                                                                                                                                                                                                                                                                                                                        power?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                                                        sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                        status?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        voltage?: number;
                                                                                                                                                                                                                                                                                                                                                                                                        [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                    Indexable

                                                                                                                                                                                                                                                                                                                                                                                                    • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                                                      Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    current?: number
                                                                                                                                                                                                                                                                                                                                                                                                    doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    model: string

                                                                                                                                                                                                                                                                                                                                                                                                    Device model

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    modelName: string

                                                                                                                                                                                                                                                                                                                                                                                                    Model name string

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    power?: number
                                                                                                                                                                                                                                                                                                                                                                                                    rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                                                    Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    state: boolean

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    status?: number

                                                                                                                                                                                                                                                                                                                                                                                                    Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                    voltage?: number
                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/RelaySwitchStatus.html b/docs/interfaces/RelaySwitchStatus.html new file mode 100644 index 00000000..35a7543a --- /dev/null +++ b/docs/interfaces/RelaySwitchStatus.html @@ -0,0 +1,16 @@ +RelaySwitchStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                      Interface RelaySwitchStatus

                                                                                                                                                                                                                                                                                                                                                                                                      Relay Switch specific types

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      interface RelaySwitchStatus {
                                                                                                                                                                                                                                                                                                                                                                                                          battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                          connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                          deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                          electricCurrent?: number;
                                                                                                                                                                                                                                                                                                                                                                                                          electricityOfDay?: number;
                                                                                                                                                                                                                                                                                                                                                                                                          power: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                          updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                          version?: string;
                                                                                                                                                                                                                                                                                                                                                                                                          voltage?: number;
                                                                                                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                                                                                                      Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                      battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                      Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                      Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                                      Device ID

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      electricCurrent?: number
                                                                                                                                                                                                                                                                                                                                                                                                      electricityOfDay?: number
                                                                                                                                                                                                                                                                                                                                                                                                      power: "on" | "off"
                                                                                                                                                                                                                                                                                                                                                                                                      updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                                      Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      version?: string

                                                                                                                                                                                                                                                                                                                                                                                                      Firmware version

                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                      voltage?: number
                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/RemoteStatus.html b/docs/interfaces/RemoteStatus.html new file mode 100644 index 00000000..c5a838ab --- /dev/null +++ b/docs/interfaces/RemoteStatus.html @@ -0,0 +1,12 @@ +RemoteStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                        Interface RemoteStatus

                                                                                                                                                                                                                                                                                                                                                                                                        Remote specific types

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        interface RemoteStatus {
                                                                                                                                                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                            connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                            updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                            version?: string;
                                                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                        battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                        Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                        Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                                        Device ID

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                                        Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        version?: string

                                                                                                                                                                                                                                                                                                                                                                                                        Firmware version

                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/Rule.html b/docs/interfaces/Rule.html deleted file mode 100644 index 18406e84..00000000 --- a/docs/interfaces/Rule.html +++ /dev/null @@ -1,9 +0,0 @@ -Rule | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                          Interface Rule

                                                                                                                                                                                                                                                                                                                                                                                                          interface Rule {
                                                                                                                                                                                                                                                                                                                                                                                                              enum?: unknown[];
                                                                                                                                                                                                                                                                                                                                                                                                              max?: number;
                                                                                                                                                                                                                                                                                                                                                                                                              maxBytes?: number;
                                                                                                                                                                                                                                                                                                                                                                                                              min?: number;
                                                                                                                                                                                                                                                                                                                                                                                                              minBytes?: number;
                                                                                                                                                                                                                                                                                                                                                                                                              pattern?: RegExp;
                                                                                                                                                                                                                                                                                                                                                                                                              required?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                              type?: "string" | "boolean" | "object" | "float" | "integer" | "array";
                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                          enum?: unknown[]
                                                                                                                                                                                                                                                                                                                                                                                                          max?: number
                                                                                                                                                                                                                                                                                                                                                                                                          maxBytes?: number
                                                                                                                                                                                                                                                                                                                                                                                                          min?: number
                                                                                                                                                                                                                                                                                                                                                                                                          minBytes?: number
                                                                                                                                                                                                                                                                                                                                                                                                          pattern?: RegExp
                                                                                                                                                                                                                                                                                                                                                                                                          required?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                          type?: "string" | "boolean" | "object" | "float" | "integer" | "array"
                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/SceneListResponse.html b/docs/interfaces/SceneListResponse.html new file mode 100644 index 00000000..b3d1f004 --- /dev/null +++ b/docs/interfaces/SceneListResponse.html @@ -0,0 +1,3 @@ +SceneListResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                            Interface SceneListResponse

                                                                                                                                                                                                                                                                                                                                                                                                            Scene list response

                                                                                                                                                                                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                                                                                                                                                                                            interface SceneListResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                sceneList: APIScene[];
                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                            sceneList: APIScene[]
                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/ServiceData.html b/docs/interfaces/ServiceData.html deleted file mode 100644 index fb639248..00000000 --- a/docs/interfaces/ServiceData.html +++ /dev/null @@ -1,2 +0,0 @@ -ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                              Interface ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                              interface ServiceData {
                                                                                                                                                                                                                                                                                                                                                                                                                  model: string;
                                                                                                                                                                                                                                                                                                                                                                                                                  [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                                                                                                                              Indexable

                                                                                                                                                                                                                                                                                                                                                                                                              • [key: string]: unknown
                                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                              model: string
                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/StripCommands.html b/docs/interfaces/StripCommands.html new file mode 100644 index 00000000..c644f59b --- /dev/null +++ b/docs/interfaces/StripCommands.html @@ -0,0 +1,10 @@ +StripCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                Interface StripCommands

                                                                                                                                                                                                                                                                                                                                                                                                                interface StripCommands {
                                                                                                                                                                                                                                                                                                                                                                                                                    sendCommandSequence?: (
                                                                                                                                                                                                                                                                                                                                                                                                                        commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                                                                                                                    ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                                                                                                                        commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                                                                                                                    ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    setBrightness: (brightness: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    setColor: (red: number, green: number, blue: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    setColorTemp?: (
                                                                                                                                                                                                                                                                                                                                                                                                                        minTemp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                        maxTemp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                        temp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                    ) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    setColorTemperature: (temperature: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    setEffect?: (effectName: string, speed?: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    turnOff: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                    turnOn: () => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                sendCommandSequence?: (commands: (() => Promise<boolean>)[]) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                sendMultipleCommands?: (
                                                                                                                                                                                                                                                                                                                                                                                                                    commands: (() => Promise<boolean>)[],
                                                                                                                                                                                                                                                                                                                                                                                                                ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                setBrightness: (brightness: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                setColor: (red: number, green: number, blue: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                setColorTemp?: (
                                                                                                                                                                                                                                                                                                                                                                                                                    minTemp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                    maxTemp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                    temp: number,
                                                                                                                                                                                                                                                                                                                                                                                                                ) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                setColorTemperature: (temperature: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                setEffect?: (effectName: string, speed?: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                turnOff: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                turnOn: () => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/StripServiceData.html b/docs/interfaces/StripServiceData.html new file mode 100644 index 00000000..d24d242f --- /dev/null +++ b/docs/interfaces/StripServiceData.html @@ -0,0 +1,35 @@ +StripServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                  Interface StripServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                  Strip Light BLE Service Data

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  interface StripServiceData {
                                                                                                                                                                                                                                                                                                                                                                                                                      battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      blue?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      channel2State?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      colorMode?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      colorTemperature?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      delay?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      doorOpen?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      green?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      inMotion?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      lockState?: "locked" | "unlocked" | "jammed";
                                                                                                                                                                                                                                                                                                                                                                                                                      mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep";
                                                                                                                                                                                                                                                                                                                                                                                                                      model: string;
                                                                                                                                                                                                                                                                                                                                                                                                                      modelName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                      preset?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      rawData?: Buffer<ArrayBufferLike>;
                                                                                                                                                                                                                                                                                                                                                                                                                      red?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      sequenceNumber?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                      status?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                      [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                                                                                                                                                                                                  Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                  Indexable

                                                                                                                                                                                                                                                                                                                                                                                                                  • [key: string]: unknown

                                                                                                                                                                                                                                                                                                                                                                                                                    Allow model-specific parser extensions

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                  battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                                  Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  blue?: number
                                                                                                                                                                                                                                                                                                                                                                                                                  brightness: number
                                                                                                                                                                                                                                                                                                                                                                                                                  channel2State?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed relay channel 2 state where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  colorMode?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                  colorTemperature?: number
                                                                                                                                                                                                                                                                                                                                                                                                                  delay?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                  doorOpen?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed door-open flag where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  green?: number
                                                                                                                                                                                                                                                                                                                                                                                                                  inMotion?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed movement state where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  lockState?: "locked" | "unlocked" | "jammed"

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed lock state where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  mode?: "press" | "switch" | "customize" | "auto" | "manual" | "sleep"

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed mode where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  model: string

                                                                                                                                                                                                                                                                                                                                                                                                                  Device model

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  modelName: string

                                                                                                                                                                                                                                                                                                                                                                                                                  Model name string

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  preset?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                  rawData?: Buffer<ArrayBufferLike>

                                                                                                                                                                                                                                                                                                                                                                                                                  Raw service data buffer

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  red?: number
                                                                                                                                                                                                                                                                                                                                                                                                                  sequenceNumber?: number

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed sequence number where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  state: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed on/off state where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  status?: number

                                                                                                                                                                                                                                                                                                                                                                                                                  Parsed lock raw status value where available

                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/StripStatus.html b/docs/interfaces/StripStatus.html new file mode 100644 index 00000000..ca1008c5 --- /dev/null +++ b/docs/interfaces/StripStatus.html @@ -0,0 +1,16 @@ +StripStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                    Interface StripStatus

                                                                                                                                                                                                                                                                                                                                                                                                                    Strip Light specific types

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    interface StripStatus {
                                                                                                                                                                                                                                                                                                                                                                                                                        battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                        brightness?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                        color?: { b: number; g: number; r: number };
                                                                                                                                                                                                                                                                                                                                                                                                                        colorTemperature?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                        connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                                        deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                        power: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                                        updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                                        version?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                                    battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                                    Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    brightness?: number
                                                                                                                                                                                                                                                                                                                                                                                                                    color?: { b: number; g: number; r: number }
                                                                                                                                                                                                                                                                                                                                                                                                                    colorTemperature?: number
                                                                                                                                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                                    Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                                                    Device ID

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    power: "on" | "off"
                                                                                                                                                                                                                                                                                                                                                                                                                    updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                                                    Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    version?: string

                                                                                                                                                                                                                                                                                                                                                                                                                    Firmware version

                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/SwitchBotBLEDevice.html b/docs/interfaces/SwitchBotBLEDevice.html deleted file mode 100644 index 398506c1..00000000 --- a/docs/interfaces/SwitchBotBLEDevice.html +++ /dev/null @@ -1,27 +0,0 @@ -SwitchBotBLEDevice | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                      Interface SwitchBotBLEDevice

                                                                                                                                                                                                                                                                                                                                                                                                                      interface SwitchBotBLEDevice {
                                                                                                                                                                                                                                                                                                                                                                                                                          AirPurifier: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          AirPurifierTable: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          BlindTilt: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Bot: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          CeilingLight: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          CeilingLightPro: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          ColorBulb: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          ContactSensor: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Curtain: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Curtain3: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Hub2: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Hub3: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Humidifier: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Lock: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          LockPro: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Meter: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          MeterPlus: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          MeterPro: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          MeterProCO2: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          MotionSensor: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          OutdoorMeter: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          PlugMiniJP: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          PlugMiniUS: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          PresenceSensor: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          StripLight: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                          Unknown: DeviceInfo;
                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                                      AirPurifier: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      AirPurifierTable: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      BlindTilt: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Bot: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      CeilingLight: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      CeilingLightPro: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      ColorBulb: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      ContactSensor: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Curtain: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Curtain3: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Hub2: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Hub3: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Humidifier: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Lock: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      LockPro: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Meter: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      MeterPlus: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      MeterPro: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      MeterProCO2: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      MotionSensor: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      OutdoorMeter: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      PlugMiniJP: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      PlugMiniUS: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      PresenceSensor: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      StripLight: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      Unknown: DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/SwitchBotConfig.html b/docs/interfaces/SwitchBotConfig.html new file mode 100644 index 00000000..f666cd41 --- /dev/null +++ b/docs/interfaces/SwitchBotConfig.html @@ -0,0 +1,39 @@ +SwitchBotConfig | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                        Interface SwitchBotConfig

                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBot configuration options

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        interface SwitchBotConfig {
                                                                                                                                                                                                                                                                                                                                                                                                                            _internal?: { forceAPI?: boolean; forceBLE?: boolean };
                                                                                                                                                                                                                                                                                                                                                                                                                            baseURL?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                            detailedErrors?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            enableBLE?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            enableCircuitBreaker?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            enableConnectionIntelligence?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            enableFallback?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            enableRetry?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                            logger?: {
                                                                                                                                                                                                                                                                                                                                                                                                                                debug: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                                error: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                                info: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                                warn: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                            };
                                                                                                                                                                                                                                                                                                                                                                                                                            logLevel?: LogLevel;
                                                                                                                                                                                                                                                                                                                                                                                                                            maxRetryAttempts?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                            noble?: any;
                                                                                                                                                                                                                                                                                                                                                                                                                            retryInitialDelayMs?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                            retryMaxDelayMs?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                            scanTimeout?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                            secret?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                            token?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                            [key: string]: any;
                                                                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                                                                        Indexable

                                                                                                                                                                                                                                                                                                                                                                                                                        • [key: string]: any

                                                                                                                                                                                                                                                                                                                                                                                                                          Additional custom options can be added as needed

                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                        _internal?: { forceAPI?: boolean; forceBLE?: boolean }

                                                                                                                                                                                                                                                                                                                                                                                                                        Internal options for testing and advanced use (not part of public API)

                                                                                                                                                                                                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                                                                                                                                                                                                        Type Declaration

                                                                                                                                                                                                                                                                                                                                                                                                                        • OptionalforceAPI?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                          Force use of API for testing (overrides intelligent selection)

                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                        • OptionalforceBLE?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                          Force use of BLE for testing (overrides intelligent selection)

                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                        baseURL?: string

                                                                                                                                                                                                                                                                                                                                                                                                                        OpenAPI base URL (optional - defaults to official API)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        detailedErrors?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable detailed error reporting in command results (default: false)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        enableBLE?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable BLE scanning (default: true on Linux)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        enableCircuitBreaker?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable circuit breaker for connection reliability (default: true)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        enableConnectionIntelligence?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable intelligent connection selection based on success history (default: true)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        enableFallback?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable BLE to API fallback on errors (default: true)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        enableRetry?: boolean

                                                                                                                                                                                                                                                                                                                                                                                                                        Enable automatic retry with exponential backoff (default: true)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        logger?: {
                                                                                                                                                                                                                                                                                                                                                                                                                            debug: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                            error: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                            info: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                            warn: (message: string, ...args: any[]) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                                                                        Custom logger instance (optional)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        logLevel?: LogLevel

                                                                                                                                                                                                                                                                                                                                                                                                                        Log level (default: WARN)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        maxRetryAttempts?: number

                                                                                                                                                                                                                                                                                                                                                                                                                        Maximum retry attempts per command (default: 3)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        noble?: any

                                                                                                                                                                                                                                                                                                                                                                                                                        Noble instance (optional - for custom BLE configuration)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        retryInitialDelayMs?: number

                                                                                                                                                                                                                                                                                                                                                                                                                        Initial retry delay in milliseconds (default: 100)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        retryMaxDelayMs?: number

                                                                                                                                                                                                                                                                                                                                                                                                                        Maximum retry delay in milliseconds (default: 5000)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        scanTimeout?: number

                                                                                                                                                                                                                                                                                                                                                                                                                        BLE scan timeout in milliseconds (default: 10000)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        secret?: string

                                                                                                                                                                                                                                                                                                                                                                                                                        OpenAPI secret (optional - required for API/Hybrid mode)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        token?: string

                                                                                                                                                                                                                                                                                                                                                                                                                        OpenAPI token (optional - required for API/Hybrid mode)

                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/SwitchBotScanner.html b/docs/interfaces/SwitchBotScanner.html deleted file mode 100644 index 29ee4737..00000000 --- a/docs/interfaces/SwitchBotScanner.html +++ /dev/null @@ -1,6 +0,0 @@ -SwitchBotScanner | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                          Interface SwitchBotScanner

                                                                                                                                                                                                                                                                                                                                                                                                                          BLE discovery and wait methods for SwitchBot devices.

                                                                                                                                                                                                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                                                                                                                                                                                                          interface SwitchBotScanner {
                                                                                                                                                                                                                                                                                                                                                                                                                              discover: (
                                                                                                                                                                                                                                                                                                                                                                                                                                  args: { duration?: number; id?: string; model: string; quick: boolean },
                                                                                                                                                                                                                                                                                                                                                                                                                              ) => Promise<unknown>;
                                                                                                                                                                                                                                                                                                                                                                                                                              wait: (ms: number) => void;
                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                          discover: (
                                                                                                                                                                                                                                                                                                                                                                                                                              args: { duration?: number; id?: string; model: string; quick: boolean },
                                                                                                                                                                                                                                                                                                                                                                                                                          ) => Promise<unknown>

                                                                                                                                                                                                                                                                                                                                                                                                                          Discover BLE devices based on filter criteria

                                                                                                                                                                                                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                                                                                                                                                                                                          wait: (ms: number) => void

                                                                                                                                                                                                                                                                                                                                                                                                                          Wait for given milliseconds

                                                                                                                                                                                                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/TemperatureServiceDataBase.html b/docs/interfaces/TemperatureServiceDataBase.html deleted file mode 100644 index e311ffcc..00000000 --- a/docs/interfaces/TemperatureServiceDataBase.html +++ /dev/null @@ -1,10 +0,0 @@ -TemperatureServiceDataBase | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                            Interface TemperatureServiceDataBase

                                                                                                                                                                                                                                                                                                                                                                                                                            Base interface for temperature-humidity meter devices.

                                                                                                                                                                                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                                                                                                                                                                                            interface TemperatureServiceDataBase {
                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                celsius: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                fahrenheit: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                fahrenheit_mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                model: SwitchBotBLEModel;
                                                                                                                                                                                                                                                                                                                                                                                                                                modelFriendlyName: SwitchBotBLEModelFriendlyName;
                                                                                                                                                                                                                                                                                                                                                                                                                                modelName: SwitchBotBLEModelName;
                                                                                                                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                                                                                                                            Hierarchy

                                                                                                                                                                                                                                                                                                                                                                                                                            • BLEServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                              • TemperatureServiceDataBase
                                                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number
                                                                                                                                                                                                                                                                                                                                                                                                                            celsius: number
                                                                                                                                                                                                                                                                                                                                                                                                                            fahrenheit: number
                                                                                                                                                                                                                                                                                                                                                                                                                            fahrenheit_mode: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                            humidity: number
                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/VacuumCommands.html b/docs/interfaces/VacuumCommands.html new file mode 100644 index 00000000..e49fa979 --- /dev/null +++ b/docs/interfaces/VacuumCommands.html @@ -0,0 +1,8 @@ +VacuumCommands | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                              Interface VacuumCommands

                                                                                                                                                                                                                                                                                                                                                                                                                              interface VacuumCommands {
                                                                                                                                                                                                                                                                                                                                                                                                                                  cleanUp: (protocolVersion: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                                  getBattery?: () => number | undefined;
                                                                                                                                                                                                                                                                                                                                                                                                                                  getDustbinBoundStatus?: () => boolean | undefined;
                                                                                                                                                                                                                                                                                                                                                                                                                                  getDustbinConnectedStatus?: () => boolean | undefined;
                                                                                                                                                                                                                                                                                                                                                                                                                                  getNetworkConnectedStatus?: () => boolean | undefined;
                                                                                                                                                                                                                                                                                                                                                                                                                                  getWorkStatus?: () => number | undefined;
                                                                                                                                                                                                                                                                                                                                                                                                                                  returnToDock: (protocolVersion: number) => Promise<boolean>;
                                                                                                                                                                                                                                                                                                                                                                                                                              }

                                                                                                                                                                                                                                                                                                                                                                                                                              Implemented by

                                                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                                              cleanUp: (protocolVersion: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                              getBattery?: () => number | undefined
                                                                                                                                                                                                                                                                                                                                                                                                                              getDustbinBoundStatus?: () => boolean | undefined
                                                                                                                                                                                                                                                                                                                                                                                                                              getDustbinConnectedStatus?: () => boolean | undefined
                                                                                                                                                                                                                                                                                                                                                                                                                              getNetworkConnectedStatus?: () => boolean | undefined
                                                                                                                                                                                                                                                                                                                                                                                                                              getWorkStatus?: () => number | undefined
                                                                                                                                                                                                                                                                                                                                                                                                                              returnToDock: (protocolVersion: number) => Promise<boolean>
                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/VacuumStatus.html b/docs/interfaces/VacuumStatus.html new file mode 100644 index 00000000..8fa2480a --- /dev/null +++ b/docs/interfaces/VacuumStatus.html @@ -0,0 +1,16 @@ +VacuumStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                Interface VacuumStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                Vacuum specific types

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                interface VacuumStatus {
                                                                                                                                                                                                                                                                                                                                                                                                                                    battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                    connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                    dustbinBound?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                    dustbinConnected?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                    networkConnected?: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                    updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                                                    version?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                    workStatus?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                }

                                                                                                                                                                                                                                                                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                                                Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                                                Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                                                                Device ID

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                dustbinBound?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                dustbinConnected?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                networkConnected?: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                                                                Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                version?: string

                                                                                                                                                                                                                                                                                                                                                                                                                                Firmware version

                                                                                                                                                                                                                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                                                                                                                                                                                                                workStatus?: number
                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/WebhookConfig.html b/docs/interfaces/WebhookConfig.html new file mode 100644 index 00000000..ad290537 --- /dev/null +++ b/docs/interfaces/WebhookConfig.html @@ -0,0 +1,4 @@ +WebhookConfig | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                  Interface WebhookConfig

                                                                                                                                                                                                                                                                                                                                                                                                                                  Webhook configuration

                                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                                  interface WebhookConfig {
                                                                                                                                                                                                                                                                                                                                                                                                                                      deviceList?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                      url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                  deviceList?: string
                                                                                                                                                                                                                                                                                                                                                                                                                                  url: string
                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/WebhookDetail.html b/docs/interfaces/WebhookDetail.html deleted file mode 100644 index 04abfc41..00000000 --- a/docs/interfaces/WebhookDetail.html +++ /dev/null @@ -1,6 +0,0 @@ -WebhookDetail | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                    Interface WebhookDetail

                                                                                                                                                                                                                                                                                                                                                                                                                                    interface WebhookDetail {
                                                                                                                                                                                                                                                                                                                                                                                                                                        createTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceList: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                        enable: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                        lastUpdateTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                        url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                    createTime: number
                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceList: string
                                                                                                                                                                                                                                                                                                                                                                                                                                    enable: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                    lastUpdateTime: number
                                                                                                                                                                                                                                                                                                                                                                                                                                    url: string
                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/WebhookDetails.html b/docs/interfaces/WebhookDetails.html new file mode 100644 index 00000000..e51cf77b --- /dev/null +++ b/docs/interfaces/WebhookDetails.html @@ -0,0 +1,7 @@ +WebhookDetails | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                      Interface WebhookDetails

                                                                                                                                                                                                                                                                                                                                                                                                                                      Webhook details

                                                                                                                                                                                                                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                                                                                                                                                                                                                      interface WebhookDetails {
                                                                                                                                                                                                                                                                                                                                                                                                                                          createTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                          deviceList: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                          enable: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                          lastUpdateTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                          url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                      createTime: number
                                                                                                                                                                                                                                                                                                                                                                                                                                      deviceList: string
                                                                                                                                                                                                                                                                                                                                                                                                                                      enable: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                      lastUpdateTime: number
                                                                                                                                                                                                                                                                                                                                                                                                                                      url: string
                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/WebhookQueryResponse.html b/docs/interfaces/WebhookQueryResponse.html new file mode 100644 index 00000000..c7542ec9 --- /dev/null +++ b/docs/interfaces/WebhookQueryResponse.html @@ -0,0 +1,5 @@ +WebhookQueryResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                        Interface WebhookQueryResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                        Webhook query response

                                                                                                                                                                                                                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                                                                                                                                                                                                                        interface WebhookQueryResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                            body: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                urls: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                    createTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceList: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    lastUpdateTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                }[];
                                                                                                                                                                                                                                                                                                                                                                                                                                            };
                                                                                                                                                                                                                                                                                                                                                                                                                                            message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                            statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                        body: {
                                                                                                                                                                                                                                                                                                                                                                                                                                            urls: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                createTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                deviceList: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                lastUpdateTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                            }[];
                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                        message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                        statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/WebhookSetupResponse.html b/docs/interfaces/WebhookSetupResponse.html new file mode 100644 index 00000000..ed1ac4a6 --- /dev/null +++ b/docs/interfaces/WebhookSetupResponse.html @@ -0,0 +1,5 @@ +WebhookSetupResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                          Interface WebhookSetupResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                          Webhook setup response

                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                          interface WebhookSetupResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                              body: any;
                                                                                                                                                                                                                                                                                                                                                                                                                                              message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                              statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                          body: any
                                                                                                                                                                                                                                                                                                                                                                                                                                          message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                          statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/ad.html b/docs/interfaces/ad.html deleted file mode 100644 index a9d8300c..00000000 --- a/docs/interfaces/ad.html +++ /dev/null @@ -1,5 +0,0 @@ -ad | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                            Interface ad

                                                                                                                                                                                                                                                                                                                                                                                                                                            interface ad {
                                                                                                                                                                                                                                                                                                                                                                                                                                                address: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                id: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                rssi: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                serviceData:
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | botServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | colorBulbServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | contactSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | curtainServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | curtain3ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | stripLightServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | lockServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | lockProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | meterServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | meterPlusServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | meterProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | meterProCO2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | outdoorMeterServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | motionSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | presenceSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | plugMiniUSServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | plugMiniJPServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | blindTiltServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | ceilingLightServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | ceilingLightProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | hub2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | hub3ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | batteryCirculatorFanServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | waterLeakDetectorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | humidifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | humidifier2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | robotVacuumCleanerServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | keypadDetectorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | relaySwitch1ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | relaySwitch1PMServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | remoteServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | airPurifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                    | airPurifierTableServiceData;
                                                                                                                                                                                                                                                                                                                                                                                                                                                [key: string]: unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                            }

                                                                                                                                                                                                                                                                                                                                                                                                                                            Indexable

                                                                                                                                                                                                                                                                                                                                                                                                                                            • [key: string]: unknown
                                                                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                            address: string
                                                                                                                                                                                                                                                                                                                                                                                                                                            id: string
                                                                                                                                                                                                                                                                                                                                                                                                                                            rssi: number
                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/body.html b/docs/interfaces/body.html deleted file mode 100644 index bf781691..00000000 --- a/docs/interfaces/body.html +++ /dev/null @@ -1,3 +0,0 @@ -body | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                              Interface body

                                                                                                                                                                                                                                                                                                                                                                                                                                              interface body {
                                                                                                                                                                                                                                                                                                                                                                                                                                                  deviceList: device[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                  infraredRemoteList: infraredRemoteList;
                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                              deviceList: device[]
                                                                                                                                                                                                                                                                                                                                                                                                                                              infraredRemoteList: infraredRemoteList
                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/bodyChange.html b/docs/interfaces/bodyChange.html deleted file mode 100644 index f90b249c..00000000 --- a/docs/interfaces/bodyChange.html +++ /dev/null @@ -1,4 +0,0 @@ -bodyChange | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                Interface bodyChange

                                                                                                                                                                                                                                                                                                                                                                                                                                                interface bodyChange {
                                                                                                                                                                                                                                                                                                                                                                                                                                                    command: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    commandType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    parameter: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                command: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                commandType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                parameter: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/deleteWebhookResponse.html b/docs/interfaces/deleteWebhookResponse.html deleted file mode 100644 index 3415e9ca..00000000 --- a/docs/interfaces/deleteWebhookResponse.html +++ /dev/null @@ -1,4 +0,0 @@ -deleteWebhookResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Interface deleteWebhookResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                  interface deleteWebhookResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                                      body: object;
                                                                                                                                                                                                                                                                                                                                                                                                                                                      message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                      statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                  body: object
                                                                                                                                                                                                                                                                                                                                                                                                                                                  message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                  statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/device.html b/docs/interfaces/device.html deleted file mode 100644 index 904044b5..00000000 --- a/docs/interfaces/device.html +++ /dev/null @@ -1,7 +0,0 @@ -device | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Interface device

                                                                                                                                                                                                                                                                                                                                                                                                                                                    interface device {
                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        enableCloudService: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        hubDeviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        version?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                    }

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceId: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceName: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                    enableCloudService: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                                    hubDeviceId: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                    version?: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/deviceList.html b/docs/interfaces/deviceList.html deleted file mode 100644 index f817be3c..00000000 --- a/docs/interfaces/deviceList.html +++ /dev/null @@ -1,2 +0,0 @@ -deviceList | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Interface deviceList

                                                                                                                                                                                                                                                                                                                                                                                                                                                      interface deviceList {
                                                                                                                                                                                                                                                                                                                                                                                                                                                          device: device[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                      device: device[]
                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/deviceStatus.html b/docs/interfaces/deviceStatus.html index 451e7698..96c42388 100644 --- a/docs/interfaces/deviceStatus.html +++ b/docs/interfaces/deviceStatus.html @@ -1,7 +1,12 @@ -deviceStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Interface deviceStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                        interface deviceStatus {
                                                                                                                                                                                                                                                                                                                                                                                                                                                            deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            deviceName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            deviceType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            enableCloudService: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            hubDeviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            version: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                        }

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceId: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceName: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                        deviceType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                        enableCloudService: boolean
                                                                                                                                                                                                                                                                                                                                                                                                                                                        hubDeviceId: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                        version: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                        +DeviceStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Interface DeviceStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Device status (generic - specific devices extend this)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          interface DeviceStatus {
                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                              connectionType: ConnectionType;
                                                                                                                                                                                                                                                                                                                                                                                                                                                              deviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                              updatedAt?: Date;
                                                                                                                                                                                                                                                                                                                                                                                                                                                              version?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                          }

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                          battery?: number

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Battery level (0-100)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          connectionType: ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Connection type used to retrieve status

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          deviceId: string

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Device ID

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          updatedAt?: Date

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Last updated timestamp

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          version?: string

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Firmware version

                                                                                                                                                                                                                                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/deviceStatusRequest.html b/docs/interfaces/deviceStatusRequest.html deleted file mode 100644 index 7c5c54a6..00000000 --- a/docs/interfaces/deviceStatusRequest.html +++ /dev/null @@ -1,4 +0,0 @@ -deviceStatusRequest | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Interface deviceStatusRequest

                                                                                                                                                                                                                                                                                                                                                                                                                                                            interface deviceStatusRequest {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                body: deviceStatus;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                            message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                            statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/deviceWebhook.html b/docs/interfaces/deviceWebhook.html deleted file mode 100644 index 9af849b0..00000000 --- a/docs/interfaces/deviceWebhook.html +++ /dev/null @@ -1,4 +0,0 @@ -deviceWebhook | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Interface deviceWebhook

                                                                                                                                                                                                                                                                                                                                                                                                                                                              interface deviceWebhook {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  context: deviceWebhookContext;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  eventType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  eventVersion: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                              eventType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                              eventVersion: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/deviceWebhookContext.html b/docs/interfaces/deviceWebhookContext.html deleted file mode 100644 index ff2aad0e..00000000 --- a/docs/interfaces/deviceWebhookContext.html +++ /dev/null @@ -1,4 +0,0 @@ -deviceWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Interface deviceWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                interface deviceWebhookContext {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceMac: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    timeOfSample: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                deviceMac: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                deviceType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                timeOfSample: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/interfaces/devices.html b/docs/interfaces/devices.html deleted file mode 100644 index b79d4b9b..00000000 --- a/docs/interfaces/devices.html +++ /dev/null @@ -1,4 +0,0 @@ -devices | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Interface devices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  interface devices {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      body: body;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  body: body
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/interfaces/infraredRemoteList.html b/docs/interfaces/infraredRemoteList.html deleted file mode 100644 index dab53db3..00000000 --- a/docs/interfaces/infraredRemoteList.html +++ /dev/null @@ -1,2 +0,0 @@ -infraredRemoteList | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Interface infraredRemoteList

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    interface infraredRemoteList {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        device: irdevice[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    device: irdevice[]
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/interfaces/irdevice.html b/docs/interfaces/irdevice.html deleted file mode 100644 index 571c9eed..00000000 --- a/docs/interfaces/irdevice.html +++ /dev/null @@ -1,5 +0,0 @@ -irdevice | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Interface irdevice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      interface irdevice {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          deviceId?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          deviceName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          hubDeviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          remoteType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      deviceId?: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      deviceName: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      hubDeviceId: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      remoteType: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/interfaces/pushResponse.html b/docs/interfaces/pushResponse.html deleted file mode 100644 index 27f03648..00000000 --- a/docs/interfaces/pushResponse.html +++ /dev/null @@ -1,5 +0,0 @@ -pushResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Interface pushResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Response from a device control (push) request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        -
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        interface pushResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            body: pushResponseBody;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/interfaces/queryWebhookResponse.html b/docs/interfaces/queryWebhookResponse.html deleted file mode 100644 index 6f8cb884..00000000 --- a/docs/interfaces/queryWebhookResponse.html +++ /dev/null @@ -1,4 +0,0 @@ -queryWebhookResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Interface queryWebhookResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          interface queryWebhookResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              body: WebhookDetail[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/interfaces/setupWebhookResponse.html b/docs/interfaces/setupWebhookResponse.html deleted file mode 100644 index 57f3eea9..00000000 --- a/docs/interfaces/setupWebhookResponse.html +++ /dev/null @@ -1,4 +0,0 @@ -setupWebhookResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Interface setupWebhookResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            interface setupWebhookResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                body: object;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            body: object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/interfaces/updateWebhookResponse.html b/docs/interfaces/updateWebhookResponse.html deleted file mode 100644 index 64de3950..00000000 --- a/docs/interfaces/updateWebhookResponse.html +++ /dev/null @@ -1,4 +0,0 @@ -updateWebhookResponse | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Interface updateWebhookResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              interface updateWebhookResponse {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  body: object;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  message: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  statusCode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              body: object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              message: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              statusCode: number
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/interfaces/webhookRequest.html b/docs/interfaces/webhookRequest.html deleted file mode 100644 index cc0a6a46..00000000 --- a/docs/interfaces/webhookRequest.html +++ /dev/null @@ -1,4 +0,0 @@ -webhookRequest | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Interface webhookRequest

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                interface webhookRequest {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    action: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceList: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    url: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                action: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                deviceList: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                url: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/media/BLE.md b/docs/media/BLE.md index b83f4c4a..bd063306 100644 --- a/docs/media/BLE.md +++ b/docs/media/BLE.md @@ -6,835 +6,325 @@ The `SwitchBot` class allows you to interact with SwitchBot devices using the Sw - [BLE (Bluetooth Low Energy)](#ble-bluetooth-low-energy) - [Supported OS](#supported-os) - - [Dependencies](#dependencies) - - [Importing and Setting Up](#importing-and-setting-up) - - [`SwitchBotBLE` Object](#switchbot-object) - - [`discover()` method](#discover-method) - - [`ondiscover` event handler](#ondiscover-event-handler) - - [`startScan()` method](#startscan-method) - - [`onadvertisement` event handler](#onadvertisement-event-handler) - - [`stopScan()` method](#stopscan-method) - - [`wait()` method](#wait-method) - - [`SwitchBotDevice` Object](#switchbotdevice-object) - - [Properties](#properties) - - [`getDeviceName()` method](#getdevicename-method) - - [`setDeviceName()` method](#setdevicename-method) - - [`connect()` method](#connect-method) - - [`disconnect()` method](#disconnect-method) - - [`onconnect` event handler](#onconnect-event-handler) - - [`ondisconnect` event handler](#ondisconnect-event-handler) - - [`WoHand` Object](#wohand-object) - - [`press()` method](#press-method) - - [`turnOn()` method](#turnon-method) - - [`turnOff()` method](#turnoff-method) - - [`down()` method](#down-method) - - [`up()` method](#up-method) - - [`WoCurtain` object](#wocurtain-object) - - [`open()` method](#open-method) - - [`close()` method](#close-method) - - [`pause()` method](#pause-method) - - [`runToPos()` method](#runtopos-method) - - [`WoPlugMini` object](#woplugmini-object) - - [`turnOn()` method](#turnon-method) - - [`turnOff()` method](#turnoff-method) - - [`toggle()` method](#toggle-method) - - [`WoSmartLock` object](#wosmartlock-object) - - [`lock()` method](#lock-method) - - [`unlock()` method](#unlock-method) - - [`unlock_no_unlatch()` method](#unlock_no_unlatch-method) - - [`info()` method](#info-method) - - [Advertisement data](#advertisement-data) - - [Bot (WoHand)](#bot-wohand) - - [Meter (WoSensorTH)](#meter-wosensorth) - - [Curtain (WoCurtain)](#curtain-wocurtain) - - [Contact (WoContact)](#contact-wocontact) - - [Motion (WoMotion)](#motion-womotion) - - [PlugMini (WoPlugMini)](#plugmini-woplugmini) - - [Supported Devices](#supported-devices) - - [Advertisement Data](#advertisement-data) - - [Control Device](#control-device) - - [Summary](#summary) - -## BLE (Bluetooth Low Energy) - -### Supported OS - -The node-switchbot supports only Linux-based OSes, such as Raspbian, Ubuntu, and so on. This module does not support Windows and macOS for now. (If [@stoprocent/noble](https://github.com/stoprocent/noble#readme) is installed properly, this module might work well on such OSes.) - -### Dependencies - -- [Node.js](https://nodejs.org/en/): ^20 -- [@stoprocent/noble](https://github.com/stoprocent/noble) - - Included as a dependency so no need to install manually however if for some reason your OS requires addtional libaries, see `@stoprocent/noble` [prerequisites](https://github.com/stoprocent/noble?tab=readme-ov-file#prerequisites), you will then need to reinstall `node-switchbot` or the package that you have `node-swtichbot` as a dependency. - -### Importing and Setting Up - -To use the `SwitchBotBLE` class in `node-switchbot`, you need to import it and create an instance. + # SwitchBot BLE Documentation -```typescript -import { SwitchBotBLE } from 'node-switchbot' - -// Example usage -const switchBotBLE = new SwitchBotBLE() - -try { - await switchBotBLE.startScan() -} catch (e: any) { - console.error(`Failed to start BLE scanning, Error: ${e.message ?? e}`) -} -``` - -### `SwitchBotBLE` Object - -The `SwitchBotBLE` constructor takes an argument optionally. It must be a hash object containing the properties as follows: - -| Property | Type | Required | Description | -| :------- | :---- | :------- | :-------------------------------------------------------------------------------------- | -| `noble` | Noble | option | a Noble object of the [`@stoprocent/noble`](https://github.com/stoprocent/noble) module | - -The node-switchbot module uses the [`@stoprocent/noble`](https://github.com/stoprocent/noble) module in order to interact with BLE devices. If you want to interact other BLE devices using the `@stoprocent/noble` module, you can create an `Noble` object by yourself, then pass it to this module. If you don't specify a `Noble` object to the `noble` property, this module automatically create a `Noble` object internally. - -The sample code below shows how to pass a `Noble` object to the `Switchbot` constructor. - -```Typescript -// Create a Noble object -const noble = require('@stoprocent/noble'); - -const switchBotBLE = new SwitchBotBLE({ 'noble': Noble }) -``` - -In the code snippet above, the variable `switchbot` is an `SwitchBotBLE` object. The `SwitchBotBLE` object has a lot of methods as described in sections below. - -#### `discover()` method - -The `discover` method finds devices. This method returns a `Promise` object. This method takes an argument which is a hash object containing parameters as follows: - -| Property | Type | Required | Description | -| :--------- | :------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `duration` | Integer | Optional | Duration for discovery process (msec). The default value is 5000 (msec). | -| `model` | String | Optional | `"H"`, `"T"` or `"c"`. If `"H"` is specified, this method will discover only Bots. If `"T"` is specified, this method will discover only Meters. If `"c"` is specified, this method will discover only Curtains. | -| `id` | String | Optional | If this value is set, this method will discover only a device whose ID is as same as this value. The ID is identical to the MAC address. This parameter is case-insensitive, and colons are ignored. | -| `quick` | Boolean | Optional | If this value is `true`, this method finishes the discovery process when the first device is found, then calls the `resolve()` function without waiting the specified `duration`. The default value is `false`. | - -In the code snippet below, no parameter is passed to the method: - -```Typescript -switchBotBLE.discover().then((device_list) => { - // Do something... -}).catch((error) => { - console.error(error); -}); -``` - -If no parameter is passed to the method as the code above, an `Array` object will be passed to the `resolve()` function in 5 seconds. The `Array` object contains [`SwitchbotDevice`](#SwitchbotDevice-object) objects representing the found devices. See the section "[`SwitchbotDevice`](#SwitchbotDevice-object) objects" for more details. - -If you want a quick response, you can set the `quick` property to `true`. - -```Typescript -switchBotBLE.discover({ - duration: 5000, - quick: true -}).then((device_list) => { - // Do something... -}).catch((error) => { - console.error(error); -}); -``` - -As the `quick` property is set to `true`, the `resolve()` function will be called immediately after a device is found regardless the value of the `duration` property. - -#### `ondiscover` event handler - -The `ondiscover` property on the [`Switchbot`](#Switchbot-object) object is an event handler called whenever a device is newly found in the discovery process. A [`SwitchbotDevice`](#SwitchbotDevice-object) object is passed to the callback function set to the `ondiscover` property. - -```Typescript -switchBotBLE.ondiscover = (device) => { - console.log(device.id + ' (' + device.modelName + ')'); -}; - -switchBotBLE.discover().then(() => { - console.log('The discovery process was finished.'); -}).catch((error) => { - console.error(error); -}); -``` - -The code snippet above will output the result as follows: - -``` -cb4eb903c96d (WoSensorTH) -c12e453e2008 (WoHand) -The discovery process was finished. -``` - -#### `startScan()` method - -The `startScan()` method starts to scan advertising packets coming from devices. This method takes an argument which is a hash object containing the parameters as follows: - -| Property | Type | Required | Description | -| :------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | String | Optional | `"H"`, `"T"`, `"c"`, `"g"` or `"j"`. If `"H"` is specified, this method will discover only Bots. If `"T"` is specified, this method will discover only Meters. If `"c"` is specified, this method will discover only Curtains. If `"g"` or `"j"` is specified, this method will discover only (US/JP) Plug Minis. | -| `id` | String | Optional | If this value is set, this method will discover only a device whose ID is as same as this value. The ID is identical to the MAC address. This value is case-insensitive, and colons are ignored. | - -Whenever a packet is received, the callback function set to the [`onadvertisement`](#Switchbot-onadvertisement-event-handler) property of the [`Switchbot`](#Switchbot-object) object will be called. When a packet is received, a hash object representing the packet will be passed to the callback function. - -```Typescript -// Set a callback function called when a packet is received -switchBotBLE.onadvertisement = (ad) => { - console.log(ad); -}; - -// Start to scan advertising packets -switchBotBLE.startScan({ - id: 'cb:4e:b9:03:c9:6d', -}).then(() => { - // Wait for 30 seconds - return switchBotBLE.wait(30000); -}).then(() => { - // Stop to scan - switchBotBLE.stopScan(); - process.exit(); -}).catch((error) => { - console.error(error); -}); -``` - -The code snippet above will output the result as follows: - -``` -{ - id: 'cb4eb903c96d', - address: 'cb:4e:b9:03:c9:6d', - rssi: -65, - serviceData: { - model: 'T', - modelName: 'WoSensorTH', - celsius: 25.8, - fahrenheit: 78.4, - fahrenheit_mode: false, - humidity: 43, - battery: 100 - } -} -... -``` + BLE support in `node-switchbot` is part of the v4 unified architecture. The primary API is the `SwitchBot` class, which can use BLE directly, OpenAPI directly, or both together with automatic fallback. -The `serviceData` property depends on the model of the device. See the section "[Advertisement data](#Advertisement-data)" for the details of the data format. + This document covers: -#### `onadvertisement` event handler + - BLE support and prerequisites on macOS and Linux + - BLE-first usage through the unified `SwitchBot` class + - Bot password protection over BLE + - Low-level BLE helpers for advanced use: `BLEScanner` and `BLEConnection` -If a callback function is set to the `onadvertisement` property, the callback function will be called whenever an advertising packet is received from a device during the scan is active (from the moment when the [`startScan()`](#startscan-method) method is called, to the moment when the [`stopScan()`](#Switchbot-stopScan-method) method is called). + ## v4 BLE Model -```typescript -switchBotBLE.onadvertisement = async (ad: any) => { - try { - this.bleEventHandler[ad.address]?.(ad.serviceData) - } catch (e: any) { - await this.errorLog(`Failed to handle BLE event, Error: ${e.message ?? e}`) - } -} -``` + In v4.0.0, BLE is no longer a separate top-level workflow that you have to adopt in isolation. Instead: -See the section "[`startScan()` method](#startscan-method)" for details. + - `SwitchBot` is the main public entry point + - BLE is used when `enableBLE: true` + - OpenAPI can be used as fallback when credentials are present + - Devices are accessed through `switchbot.devices` + - Per-device commands automatically choose the best available connection path -#### `stopScan()` method + ## Supported Platforms -The `stopScan()` method stops to scan advertising packets coming from devices. This method returns nothing. Note that this method is _not_ asynchronous but synchronous unlike the other methods. See the section "[`startScan()` method](#startscan-method)" for details. + BLE is supported on: -```typescript -try { - switchBotBLE.stopScan() - console.log('Stopped BLE scanning to close listening.') -} catch (e: any) { - console.error(`Failed to stop BLE scanning, Error: ${e.message ?? e}`) -} -``` - -#### `wait()` method + - macOS + - Linux, including Ubuntu, Debian, Raspbian, and similar distributions -The `wait()` method waits for the specified milliseconds. This method takes an integer representing the duration (millisecond). This method returns a `Promise` object. + BLE is not supported on Windows in this package. On Windows, use API-only mode through the unified `SwitchBot` class. -This method has nothing to do with Switchbot devices. It's just a utility method. See the section "[Quick Start](#Quick-Start)" for details of the usage of this method. - -```typescript -await switchBotBLE.wait(1000) -``` + ## Requirements -### `SwitchBotDevice` Object + - Node.js `^20 || ^22 || ^24` + - `@stoprocent/noble` is included as a dependency -The `SwitchbotDevice` object represents a Switchbot device (Bot, Meter, Curtain, Contact or Motion), which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + ## Prerequisites -Actually, the `SwitchbotDevice` object is a super class of the [`WoHand`](#SwitchbotDeviceWoHand-object) and `WoSensorTH` objects. The [`WoHand`](#SwitchbotDeviceWoHand-object) object represents a Bot, the `WoSensorTH` object represents a Meter. + ### macOS -You can use the properties and methods described in this section on Bot, Meter, Curtain, Contact and Motion. See the section "[`WoHand` object](#SwitchbotDeviceWoHand-object)" for the details of the functionalities available only on Bot. For now, `WoSensorTH` object has no additional functionality. + - Install Xcode from the App Store + - Allow Bluetooth access for your terminal application in System Settings or System Preferences -#### Properties + ### Linux (Ubuntu, Debian, Raspbian) -The `SwitchbotDevice` object supports the properties as follows: + Install required packages: -| Property | Type | Description | -| :---------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | String | ID of the device. (e.g., `"cb4eb903c96d"`) | -| `address` | String | MAC address of the device. Basically it is as same as the value of the `id` except that this value includes `:` in the string. (e.g., `"cb:4e:b9:03:c9:6d"`) | -| `model` | String | This value is `"H"` "Bot (WoHand)", `"T"` "Meter (WoSensorTH)", `"c"` "Curtain (WoCurtain)", `"d"` "Contact (WoContact)" or `"s"` "Motion (WoMotion)". | -| `modelName` | String | This value is `"WoHand"`, `"WoSensorTH"`, `WoCurtain`, `WoContect` or `WoMotion`. | -| `connectionState` | String | This value indicates the BLE connection state. `"connecting"`, `"connected"`, `"disconnecting"`, or `"disconnected"`. | -| `onconnect` | Function | See the section "[`onconnect` event handler](#SwitchbotDevice-onconnect-event-handler)" for details. | -| `ondisconnect` | Function | See the section "[`ondisconnect` event handler](#SwitchbotDevice-ondisconnect-event-handler)" for details. | - -#### `getDeviceName()` method - -The `getDeviceName()` method fetches the device name saved in the device. This method returns a `Promise` object. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -If the device name is fetched successfully, the device name will be passed to the `resolve()`. - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].getDeviceName(); - }) - .then((name) => { - console.log(name); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` - -The code above will output the result as follows: - -```Typescript -WoHand; -``` + ```bash + sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev + ``` -#### `setDeviceName()` method + For non-root access, also install `libcap2-bin` and grant raw socket capability to `node`: -The `setDeviceName()` method update the device name saved in the device with the name specified as the first argument. This method returns a `Promise` object. Nothing will be passed to the `resolve()` function. + ```bash + sudo apt-get install libcap2-bin + sudo setcap cap_net_raw+eip $(eval readlink -f `which node`) + ``` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + On Raspberry Pi, if BLE connections are unstable, you may need to disable the `pnat` plugin in `/etc/bluetooth/main.conf` and restart Bluetooth or reboot. -The character set of the device name saved in the device is UTF-8. The byte length of the name must be less than or equal to 20 bytes. If the name consists of only ASCII characters, up to 20 characters would be allowed. But if the name consists of multibyte characters, the upper limit of characters would be fewer than half. For example, Japanese characters could be saved at most 6 characters because most of Japanese characters consume 3 byte per each character. + ### Fedora and Other RPM-Based Linux -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].setDeviceName("Bot in kitchen"); - }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` + ```bash + sudo yum install bluez bluez-libs bluez-libs-devel + ``` -#### `connect()` method + For more platform details, see the `@stoprocent/noble` prerequisites documentation. -The `connect()` method establishes a connection with the device (i.e., pairing). This method returns a `Promise` object. If the device has already been connected, this method does nothing and calls the `resolve()` function immediately. + ## Unified BLE Usage -Most of the methods implemented in the `SwitchbotDevice` object automatically connect and disconnect the device. But this mechanism would be absolutely inefficient if you want to manipulate the device repeatedly in the short time. + ### BLE-Only Mode -The connection established using the `connect()` method is not disconnected automatically unless the [`disconnect()`](#SwitchbotDevice-disconnect-method) method is explicitly called. + Use BLE without OpenAPI credentials: -The code snippet below establishes a connection with the Bot using the `connect()` method, then puts the Bot's arm down, then waits for 5 seconds, then puts the arm down, finally disconnects the device using the [`disconnect()`](#SwitchbotDevice-disconnect-method) method: + ```typescript + import { LogLevel, SwitchBot } from 'node-switchbot' -```Typescript -let device = null; - -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - device = device_list[0]; - if (!device) { - console.log("No device was found."); - process.exit(); - } - console.log(device.modelName + " (" + device.address + ") was found."); - console.log("Connecting..."); - return device.connect(); + const switchbot = new SwitchBot({ + enableBLE: true, + enableFallback: false, + logLevel: LogLevel.INFO, }) - .then(() => { - console.log("Putting the arm down..."); - return device.down(); - }) - .then(() => { - console.log("Waiting for 5 seconds..."); - return switchBotBLE.wait(5000); - }) - .then(() => { - console.log("Putting the arm up..."); - return device.up(); - }) - .then(() => { - console.log("Disconnecting..."); - return device.disconnect(); - }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` -The result will be as follows: - -``` -WoHand (c1:2e:45:3e:20:08) was found. -Connecting... -Putting the arm down... -Waiting for 5 seconds... -Putting the arm up... -Disconnecting... -Done. -``` - -#### `disconnect()` method - -The `disconnect()` method disconnects the device. This method returns a `Promise` object. If the device has already been disconnected, this method does nothing and calls the `resolve()` function immediately. - -See the [previous section](#SwitchbotDevice-connect-method) for more details. - -#### `onconnect` event handler - -The `onconnect` event handler will be called when the connection with the device is established. Nothing will be passed to the handler. - -The code below calls the [`press()`](#SwitchbotDeviceWoHand-press-method) method, while callback functions are attached to the `onconnect` and `ondisconnect`. - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - const device = device_list[0]; - if (!device) { - console.log("No device was found."); - process.exit(); - } - console.log(device.modelName + " (" + device.address + ") was found."); - - // Set event handers - device.onconnect = () => { - console.log("Connected."); - }; - device.ondisconnect = () => { - console.log("Disconnected."); - }; - - console.log("Pressing the switch..."); - return device.press(); + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: false, + timeout: 10_000, }) - .then(() => { - console.log("Done."); - process.exit(); - }) - .catch((error) => { - console.error(error); - process.exit(); - }); -``` - -The code above will output the result as follows: - -``` -WoHand (c1:2e:45:3e:20:08) was found. -Pressing the switch... -Connected. -Disconnected. -Done. -``` - -Seeing the result, you would find the [`press()`](#SwitchbotDeviceWoHand-press-method) method automatically connects and disconnects the device. -#### `ondisconnect` event handler + console.log(`Found ${devices.length} BLE device(s)`) -The `ondisconnect` event handler will be called when the connection with the device is closed. Nothing will be passed to the handler. See the previous section "[`onconnect` event handler](#SwitchbotDevice-onconnect-event-handler)" for more details. - -### `WoHand` Object - -The `WoHand` object represents a Bot, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + const bot = switchbot.devices.get('YOUR_DEVICE_ID') + if (bot) { + await bot.press() + } -Actually, the `WoHand` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. + await switchbot.cleanup() + ``` -#### `press()` method + ### Hybrid BLE + API Mode -The `press()` method sends a press command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + Use BLE first, with automatic API fallback when needed: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ```typescript + import { LogLevel, SwitchBot } from 'node-switchbot' -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].press(); - }) - .then(() => { - console.log("Done."); + const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: true, + enableFallback: true, + enableConnectionIntelligence: true, + enableCircuitBreaker: true, + enableRetry: true, + logLevel: LogLevel.INFO, }) - .catch((error) => { - console.error(error); - }); -``` -When the Bot receives this command, the Bot's arm will be put down (stretched), then put up (retracted) in a few seconds. - -#### `turnOn()` method - -The `turnOn()` method sends a turn-on command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -When the Bot receives this command, the Bot's arm will be put down (stretched) or put up (retracted) depending on the mode setting. - -| Mode | Inverse the on/off direction | Physical position of the arm | -| :---------- | :--------------------------- | :------------------------------------ | -| Press mode | N/A | Down (stretched), then Up (retracted) | -| Switch mode | Disabled | Down (stretched) | -|   | Enabled | Up (retracted) | - -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].turnOn(); - }) - .then(() => { - console.log("Done."); + await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10_000, }) - .catch((error) => { - console.error(error); - }); -``` - -#### `turnOff()` method - -The `turnOff()` method sends a turn-off command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. -When the Bot receives this command, the Bot's arm will be put down (stretched) or put up (retracted) depending on the mode setting. + const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') + if (curtain) { + await curtain.open() + const status = await curtain.getStatus() + console.log(status) + } -| Mode | Inverse the on/off direction | Physical position of the arm | -| :---------- | :--------------------------- | :------------------------------------ | -| Press mode | N/A | Down (stretched), then Up (retracted) | -| Switch mode | Disabled | Up (retracted) | -|   | Enabled | Down (stretched) | + await switchbot.cleanup() + ``` -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].turnOff(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ## Discovery Options -#### `down()` method + `switchbot.discover()` accepts the following v4 options: -The `down()` method sends a down command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + | Property | Type | Description | + | :-- | :-- | :-- | + | `scanBLE` | `boolean` | Enable BLE discovery for this call | + | `fetchAPI` | `boolean` | Fetch devices from OpenAPI for this call | + | `timeout` | `number` | Discovery timeout in milliseconds | + | `deviceId` | `string` | Filter by SwitchBot device ID | + | `mac` | `string` | Filter by MAC address | + | `deviceType` | `string` | Filter by device type | -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ## Device Access Pattern -When the Bot receives this command, the Bot's arm will be put down (stretched) regardless of the mode setting. + After discovery, use the device manager: -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].down(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ```typescript + const devices = switchbot.devices.list() + const bot = switchbot.devices.get('YOUR_DEVICE_ID') + const curtains = switchbot.devices.getByType('WoCurtain') + ``` -#### `up()` method + Common device helpers include: -The `up()` method sends an up command to the Bot. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + - `getInfo()` + - `getName()` + - `getDeviceType()` + - `getStatus()` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + Commands vary by device class. Examples: -When the Bot receives this command, the Bot's arm will be put up (retracted) regardless of the mode setting. + - Bot: `press()`, `turnOn()`, `turnOff()`, `handUp()`, `handDown()` + - Curtain: `open()`, `close()`, `pause()`, `setPosition()` + - Plug: `turnOn()`, `turnOff()`, `toggle()` -```Typescript -switchbot - .discover({ model: "H", quick: true }) - .then((device_list) => { - return device_list[0].up(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + ## Bot Password Protection -### `WoCurtain` Object + Bot (`WoHand`) devices support password-protected BLE commands in v4. -The `WoCurtain` object represents a Curtain, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. + ### What It Adds -Actually, the `WoCurtain` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. + - Password validation for exactly 4 alphanumeric characters + - CRC32-based encrypted BLE command construction + - Automatic encrypted command execution when a password is configured + - Runtime helpers: `setPassword()`, `clearPassword()`, `hasPassword()` -#### `open()` method + ### Supported Commands -The `open()` method sends an open command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + When a password is set, these BLE Bot commands use the encrypted flow: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - `press()` + - `turnOn()` + - `turnOff()` + - `handUp()` + - `handDown()` -When the Curtain receives this command, the Curtain will open the curtain (0% position). If not calibrated, the Curtain does not move. + ### Example -The `open()` method receives an optional `mode` parameter. (See [`runToPos()`](#runtopos-method)) + ```typescript + import { LogLevel, SwitchBot, WoHand } from 'node-switchbot' -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].open(); - }) - .then(() => { - console.log("Done."); + const switchbot = new SwitchBot({ + enableBLE: true, + enableFallback: false, + logLevel: LogLevel.INFO, }) - .catch((error) => { - console.error(error); - }); -``` -#### `close()` method + await switchbot.discover({ scanBLE: true, fetchAPI: false }) -The `close()` method sends a close command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + const bot = switchbot.devices.get('YOUR_DEVICE_ID') as WoHand | undefined + if (bot) { + bot.setPassword('A1b2') -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -When the Curtain receives this command, the Curtain will close the curtain (100% position). If not calibrated, the Curtain does not move. - -The `close()` method receives an optional `mode` parameter. (See [`runToPos()`](#runtopos-method)) + if (bot.hasPassword()) { + await bot.press() + } -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].close(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + bot.clearPassword() + } -#### `pause()` method + await switchbot.cleanup() + ``` -The `pause()` method sends a pause command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + Notes: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - Passwords are stored in memory only + - The password must be configured again when your application starts + - Password-protected Bot commands require BLE and do not use OpenAPI fallback for the encrypted write path -When the Curtain receives this command, the Curtain will pause. + ## Reliability Features in BLE Workflows -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].pause(); - }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` + The v4 BLE path includes the resilience features introduced in the 4.0.0 release: -#### `runToPos()` method + - Automatic retry with exponential backoff and jitter + - Circuit breaker state management to avoid repeated failing connections + - Connection intelligence that can prefer the more reliable path over time + - Fallback hooks for custom logging, metrics, or alerting -The `runToPos()` method sends a position command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + These behaviors are primarily exposed through the unified `SwitchBot` and `SwitchBotDevice` flow rather than through manual low-level BLE orchestration. -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ## Low-Level BLE APIs -When the Curtain receives this command, the Curtain will run to the percentage position. If not calibrated, the Curtain does not move. + If you need raw scanning or connection control, v4 exports `BLEScanner` and `BLEConnection` directly. -The `open()` method sends an open command to the Curtain. This method returns a `Promise` object. Nothing will be passed to the `resove()`. + ### `BLEScanner` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + Use this for advertisement scanning and device discovery without going through `SwitchBot`. -When the Curtain receives this command, the Curtain will open the curtain (0% position). If not calibrated, the Curtain does not move. + ```typescript + import { BLEScanner } from 'node-switchbot' -| Property | Type | Required | Description | -| :-------- | :------ | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| `percent` | Integer | Required | The percentage of target position (`0-100`). (e.g., `50`) | -| `mode` | Integer | Optional | The running mode of Curtain.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                `0x00` - Performance mode.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                `0x01` - Silent mode.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                `0xff` - Default. Unspecified, from Curtain's settings. | + const scanner = new BLEScanner() -```Typescript -switchbot - .discover({ model: "c", quick: true }) - .then((device_list) => { - return device_list[0].runToPos(50); + scanner.on('discover', (advertisement) => { + console.log(advertisement) }) - .then(() => { - console.log("Done."); - }) - .catch((error) => { - console.error(error); - }); -``` - -### `WoPlugMini` Object - -The `WoPlugMini ` object represents a PlugMini, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. - -Actually, the `WoPlugMini ` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. - -#### `turnOn()` method - -The `turnOn()` method sends a turn-on command to the PlugMini. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is on (`true`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -#### `turnOff()` method - -The `turnOff()` method sends a turn-off command to the PlugMini. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is off (`false`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -#### `toggle()` method - -The `toggle()` method sends a toggle command to the PlugMini, toggling between the on and off state. This method returns a `Promise` object. A `boolean` value indicating whether the PlugMini is on (`true`) or off (`false`), is passed to the `resolve()` method of the Promise. - -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. - -### `WoSmartLock` Object - -The `WoSmartLock ` object represents a SmartLock, which is created through the discovery process triggered by the [`switchBotBLE.discover()`](#discover-method) method. - -Actually, the `WoSmartLock ` is an object inherited from the [`SwitchbotDevice`](#SwitchbotDevice-object). You can use not only the method described in this section but also the properties and methods implemented in the [`SwitchbotDevice`](#SwitchbotDevice-object) object. - -#### `setKey()` method - -The `setKey()` method initialises the key information required for encrypted communication with the SmartLock - -This must be set before any control commands are sent to the device. To obtain the key information you will need to use an external tool - see [`pySwitchbot`](https://github.com/Danielhiversen/pySwitchbot/tree/master?tab=readme-ov-file#obtaining-locks-encryption-key) project for an example script. -Or, use [`switchbot-get-encryption-key`](https://www.npmjs.com/package/switchbot-get-encryption-key) npm script. - -| Property | Type | Description | -| :-------------- | :----- | :----------------------------------------------------------------------------------------------- | -| `keyId` | String | unique2 character ID for the key. (e.g., `"ff"`) returned from the SwitchBot api for your device | -| `encryptionKey` | String | the unique encryption key returned from the SwitchBot api for your device | -#### `lock()` method + await scanner.startScan({ duration: 10_000, active: true }) + ``` -The `lock()` method sends a lock command to the SmartLock. This method returns a `Promise` object. A `boolean` value indicating whether the SmartLock is locked (`true`), is passed to the `resolve()` method of the Promise. + Public methods: -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + - `startScan(options?)` + - `stopScan()` + - `getDiscoveredDevices()` + - `getDevice(mac, bleId?)` + - `waitForDevice(mac, timeoutMs?, bleId?)` + - `destroy()` -#### `unlock()` method + Events: -The `unlock()` method sends an unlock command to the SmartLock. This method returns a `Promise` object. A `boolean` value indicating whether the SmartLock is locked (`false`), is passed to the `resolve()` method of the Promise. + - `ready` + - `state-change` + - `scan-start` + - `scan-stop` + - `discover` -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + ### `BLEConnection` -#### `unlockNoUnlatch()` method + Use this for low-level connection, write, and notification handling. -The `unlockNoUnlatch()` method sends a partial unlock command to the SmartLock, unlocking without the full unlatch. + ```typescript + import { BLEConnection } from 'node-switchbot' + import { Buffer } from 'node:buffer' -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + const connection = new BLEConnection() -#### `info()` method + await connection.connect('AA:BB:CC:DD:EE:FF') + await connection.write('AA:BB:CC:DD:EE:FF', Buffer.from([0x57, 0x01, 0x00])) + const response = await connection.read('AA:BB:CC:DD:EE:FF') -The `info()` method retreieves state information from the SmartLock, This method returns a `Promise` object. An `object` value indicating with the state infor, is passed to the `resolve()` method of the Promise. + console.log(response) -If no connection is established with the device, this method automatically establishes a connection with the device, then finally closes the connection. You don't have to call the [`connect()`](#SwitchbotDevice-connect-method) method in advance. + await connection.disconnectAll() + ``` -### Advertisement Data + Key public methods: -After the [`startScan()`](#startscan-method) method is invoked, the [`onadvertisement`](#Switchbot-onadvertisement-event-handler) event handler will be called whenever an advertising packet comes from the switchbot devices. + - `connect(mac)` + - `write(mac, data)` + - `read(mac)` + - `disconnectAll()` + - `setPersistentConnectionTimeout(timeoutMs)` + - `setEncryption(mac, keyHex, ivHex, mode?)` + - `clearEncryption(mac)` -```Typescript -// Load the node-switchbot and get a `Switchbot` constructor object -import { SwitchBotBLE } from 'node-switchbot'; -// Create a `Switchbot` object -const switchBotBLE = new SwitchBotBLE(); - -(async () => { - // Start to monitor advertisement packets - await switchBotBLE.startScan(); - // Set an event handler - switchBotBLE.onadvertisement = (ad) => { - console.log(JSON.stringify(ad, null, ' ')); - }; - // Wait 10 seconds - await switchBotBLE.wait(10000); - // Stop to monitor - switchBotBLE.stopScan(); - process.exit(); -})(); -``` - -An object containing the properties as follows will be passed to the event handler: - -| Property | Type | Description | -| :------------ | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | String | ID of the device. (e.g., `"cb4eb903c96d"`) | -| `address` | String | MAC address of the device. Basically it is as same as the value of the `id` except that this value includes `:` in the string. (e.g., `"cb:4e:b9:03:c9:6d"`) | -| `rssi` | Integer | RSSI. (e.g., `-62`) | -| `serviceData` | Object | An object including the device-specific data. | - -The structures of the `serviceData` are described in the following sections. + ## BLE-Supported Device Families -#### Bot (WoHand) - -Example of the advertisement data: - -```json -{ - "id": "c12e453e2008", - "address": "c1:2e:45:3e:20:08", - "rssi": -61, - "serviceData": { - "model": "H", - "modelName": "WoHand", - "mode": true, - "state": false, - "battery": 100 - } -} -``` - -Structure of the `serviceData`: + v4 BLE support includes, among others: -| Property | Type | Description | -| :---------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | String | This value is always `"H"`, which means "Bot (WoHand)". | -| `modelName` | String | This value is always `"WoHand"`, which means "Bot". | -| `mode` | Boolean | This indicates the mode setting. When the mode is "Switch mode", this value is `true`. When the mode is "Press mode", this value is `false`. | -| `state` | Boolean | This value indicates whether the switch status is ON or OFF. | -| `battery` | Integer | (**experimental**) This value indicates the battery level (`%`). | + - Bot + - Curtain and Roller Shade + - Blind Tilt + - Meter family + - Plug Mini family + - Lock family + - Humidifier family + - Bulb and light families + - Leak, contact, and presence sensors + - Relay switch family -The `mode` can be changed only using the official smartphone app. The node-switchbot does not support changing the mode because the BLE protocol is non-public. + Exact per-device behavior still depends on what the physical device exposes over BLE. -If the `mode` is `false`, which means the "Press mode" is selected, the `state` is always `false`. If the `mode` is `true`, which means the "Switch mode" is selected, the `state` represents the logical state (ON or OFF). Note that it does _not_ mean the physical arm position. The physical arm position depends on the setting "Inverse the on/off direction" on the official smartphone app. + ## Summary -| "Inverse the on/off direction" | Value of the `state` | Logical state | Physical arm position | -| :----------------------------- | :------------------- | :------------ | :-------------------- | -| disabled | `true` | OFF | Up (retracted) | -|   | `false` | ON | Down (stretched) | + Use `SwitchBot` for almost all v4 BLE workflows. Reach for `BLEScanner` and `BLEConnection` only when you need direct advertisement scanning or manual low-level BLE control. | enabled | `true` | OFF | Down (stretched) | |   | `false` | ON | Up (retracted) | diff --git a/docs/media/OpenAPI.md b/docs/media/OpenAPI.md index bdea49d1..aaca17da 100644 --- a/docs/media/OpenAPI.md +++ b/docs/media/OpenAPI.md @@ -1,186 +1,220 @@ # SwitchBot OpenAPI Documentation -The `SwitchBotOpenAPI` class allows you to interact with SwitchBot devices using the SwitchBot OpenAPI. This documentation provides an overview of how to install, set up, and use the various methods available in the `SwitchBotOpenAPI` class. +OpenAPI support in `node-switchbot` is part of the v4 unified architecture. The primary public API is the `SwitchBot` class, which can run in API-only mode or in hybrid BLE + OpenAPI mode. -## Table of Contents +This document covers: -- [OpenAPI](#openapi) - - [Importing and Setting Up](#importing-and-setting-up) - - [`SwitchBotOpenAPI` Object](#switchbotopenapi-object) - - [`getDevices()` Method](#getdevices-method) - - [`controlDevice()` Method](#controldevice-method) - - [`getDeviceStatus()` Method](#getdevicestatus-method) - - [`setupWebhook()` Method](#setupwebhook-method) - - [`deleteWebhook()` Method](#deletewebhook-method) - - [Logging](#logging) - - [Supported Devices](#supported-devices) +- Using OpenAPI through the unified `SwitchBot` class +- Running in API-only mode +- Using the lower-level `OpenAPIClient` directly +- Webhook and scene helpers exposed by `OpenAPIClient` -## OpenAPI +## v4 OpenAPI Model -### Importing and Setting Up +In v4.0.0: -To use the `SwitchBotOpenAPI` class, you need to import it and create an instance with your SwitchBot token and secret. +- `SwitchBot` is the recommended entry point +- OpenAPI is enabled when `token` and `secret` are provided +- You can run API-only by setting `enableBLE: false` +- You can run hybrid mode by combining credentials with `enableBLE: true` +- Discovered devices are accessed through `switchbot.devices` -```typescript -import { SwitchBotOpenAPI } from 'node-switchbot' +## Credentials -const switchBotAPI = new SwitchBotOpenAPI('your-token', 'your-secret') +To use OpenAPI, you need a SwitchBot token and secret. -// Example usage -switchBotAPI.getDevices().then((devices) => { - console.log('Devices:', devices) -}).catch((error) => { - console.error('Error getting devices:', error) -}) -``` +In the SwitchBot mobile app: -### SwitchBotOpenAPI Object +1. Open your profile +2. Open preferences +3. Tap the app version multiple times to unlock developer options +4. Copy your token and secret -The `SwitchBotOpenAPI` object provides several methods to interact with SwitchBot devices. Below are examples of how to use each method. +## API-Only Mode -#### `getDevices()` Method - -Fetches the list of devices associated with your SwitchBot account. +Use this mode on Windows or anywhere you want cloud-only operation. ```typescript -async function getDevices() { - try { - const devices = await switchBotAPI.getDevices() - console.log('Devices:', devices) - } catch (e: any) { - console.error(`failed to get devices, Error: ${e.message ?? e}`) - } -} +import { LogLevel, SwitchBot } from 'node-switchbot' -// Example usage -getDevices() -``` +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: false, + logLevel: LogLevel.INFO, +}) -#### `controlDevice()` Method +const devices = await switchbot.discover({ + scanBLE: false, + fetchAPI: true, +}) -Sends a command to control a specific device. +console.log(`Found ${devices.length} device(s) from OpenAPI`) -```typescript -async function controlDevice(deviceId, command, parameter) { - try { - const response = await switchBotAPI.controlDevice(deviceId, command, parameter) - console.log('Control Device Response:', response) - } catch (error) { - console.error('Error controlling device:', error) - } +const bot = switchbot.devices.get('YOUR_DEVICE_ID') +if (bot) { + await bot.turnOn() + const status = await bot.getStatus() + console.log(status) } -// Example usage -controlDevice('your-device-id', 'turnOn', 'default') +await switchbot.cleanup() ``` -#### `getDeviceStatus()` Method +## Hybrid Mode -Fetches the current status of a specific device. +If you want local BLE when available and cloud fallback when needed: ```typescript -async function getDeviceStatus(deviceId) { - try { - const status = await switchBotAPI.getDeviceStatus(deviceId) - console.log('Device Status:', status) - } catch (error) { - console.error('Error getting device status:', error) - } +import { LogLevel, SwitchBot } from 'node-switchbot' + +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: true, + enableFallback: true, + enableConnectionIntelligence: true, + enableCircuitBreaker: true, + enableRetry: true, + logLevel: LogLevel.INFO, +}) + +await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10_000, +}) + +const lock = switchbot.devices.get('YOUR_LOCK_ID') +if (lock) { + await lock.lock() } -// Example usage -getDeviceStatus('your-device-id') +await switchbot.cleanup() ``` -#### `setupWebhook()` Method +## Discovery Through OpenAPI -Sets up a webhook to receive events from SwitchBot devices. +When OpenAPI is enabled, `switchbot.discover()` can fetch cloud-registered devices and merge them with BLE discoveries. -```typescript -async function setupWebhook(url) { - try { - await switchBotAPI.setupWebhook(url) - console.log('Webhook setup successfully') - } catch (error) { - console.error('Error setting up webhook:', error) - } -} +Supported discovery options: -// Example usage -setupWebhook('http://your-webhook-url') +| Property | Type | Description | +| :-- | :-- | :-- | +| `scanBLE` | `boolean` | Enable BLE discovery for this call | +| `fetchAPI` | `boolean` | Enable OpenAPI device fetch for this call | +| `timeout` | `number` | Discovery timeout in milliseconds | +| `deviceId` | `string` | Filter by SwitchBot device ID | +| `mac` | `string` | Filter by MAC address | +| `deviceType` | `string` | Filter by device type | + +## Device Manager Pattern + +After discovery: + +```typescript +const devices = switchbot.devices.list() +const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') +const locks = switchbot.devices.getByType('WoSmartLock') ``` -#### `deleteWebhook()` Method +Every discovered device exposes the unified command surface for its class, regardless of whether the eventual command runs over API, BLE, or a fallback path. -Deletes an existing webhook. +## Lower-Level `OpenAPIClient` + +If you need direct access to the SwitchBot cloud API without the full hybrid layer, use `OpenAPIClient`. ```typescript -async function deleteWebhook(url) { - try { - await switchBotAPI.deleteWebhook(url) - console.log('Webhook deleted successfully') - } catch (error) { - console.error('Error deleting webhook:', error) - } -} +import { OpenAPIClient } from 'node-switchbot' + +const api = new OpenAPIClient('YOUR_TOKEN', 'YOUR_SECRET') + +const devices = await api.getDevices() +console.log(devices) + +const status = await api.getStatus('YOUR_DEVICE_ID') +console.log(status) -// Example usage -deleteWebhook('http://your-webhook-url') +await api.sendCommand('YOUR_DEVICE_ID', 'turnOn') ``` -### Logging +### Core Methods + +| Method | Description | +| :-- | :-- | +| `getDevices()` | Fetch cloud devices | +| `getStatus(deviceId)` | Fetch device status | +| `sendCommand(deviceId, command, parameter?)` | Send a raw OpenAPI command | +| `getScenes()` | Fetch scenes | +| `executeScene(sceneId)` | Run a scene | + +### Webhook Methods + +| Method | Description | +| :-- | :-- | +| `setupWebhook(config)` | Register a webhook | +| `queryWebhook(urls?)` | Query existing webhook configuration | +| `updateWebhook(config)` | Update a webhook | +| `deleteWebhook(url)` | Remove a webhook | + +### Convenience Methods -To be able to receive logging that this module is pushing out you will need to subscribt to the events. +The client also exposes convenience wrappers for common device families, including Bot and Curtain helpers. + +Examples: + +- `botPress(deviceId)` +- `botTurnOn(deviceId)` +- `botTurnOff(deviceId)` +- `curtainOpen(deviceId, speed?)` +- `curtainClose(deviceId, speed?)` +- `curtainPause(deviceId)` +- `curtainSetPosition(deviceId, position, speed?)` + +## Logging + +In v4, logging is configured through the unified constructor rather than through a legacy event-emitter API shown in older docs. + +Example using the main `SwitchBot` class: ```typescript -this.switchBotAPI.on('log', (log) => { - switch (log.level) { - case LogLevel.SUCCESS: - this.successLog(log.message) - break - case LogLevel.DEBUGSUCCESS: - this.debugSuccessLog(log.message) - break - case LogLevel.WARN: - this.warnLog(log.message) - break - case LogLevel.DEBUGWARN: - this.debugWarnLog(log.message) - break - case LogLevel.ERROR: - this.errorLog(log.message) - break - case LogLevel.DEBUGERROR: - this.debugErrorLog(log.message) - break - case LogLevel.DEBUG: - this.debugLog(log.message) - break - case LogLevel.INFO: - default: - this.infoLog(log.message) - } +const switchbot = new SwitchBot({ + token: 'YOUR_TOKEN', + secret: 'YOUR_SECRET', + enableBLE: false, + logger: { + error: console.error, + warn: console.warn, + info: console.info, + debug: console.debug, + }, }) ``` -### Supported Devices +## OpenAPI-Supported Device Families + +OpenAPI support generally includes the major SwitchBot cloud-connected device families, such as: + +- Bot +- Curtain and Roller Shade +- Meter family +- Contact and motion or presence sensors +- Plug Mini family +- Lock family +- Humidifier and air purifier family +- Bulb and strip light family +- Hub-connected devices supported by the SwitchBot cloud + +Actual availability depends on SwitchBot cloud support for the device and whether cloud service is enabled in your account. + +## Relationship to BLE -The following devices are supported. +OpenAPI docs are no longer separate from the main product model. In v4: -| Device | OpenAPI Support | Webhook Support | -| ---------------------------------------------- | --------------- | --------------- | -| SwitchBot Bot | Yes | Yes | -| SwitchBot Curtain | Yes | Yes | -| SwitchBot Meter | Yes | Yes | -| SwitchBot Motion Sensor | Yes | Yes | -| SwitchBot Contact Sensor | Yes | Yes | -| SwitchBot Plug Min | Yes | Yes | -| SwitchBot Smart Lock | Yes | Yes | -| SwitchBot Humidifier | Yes | Yes | -| SwitchBot Evaporative Humidifier (Auto-refill) | Yes | Yes | -| SwitchBot Color Bulb | Yes | Yes | -| SwitchBot LED Strip Light | Yes | Yes | +- Use [BLE.md](BLE.md) for platform-specific BLE prerequisites and low-level BLE helpers +- Use this document for cloud API behavior and `OpenAPIClient` +- Use the main README for the high-level v4 migration and quick-start path -### Summary +## Summary -The `SwitchBotOpenAPI` class provides a powerful way to interact with your SwitchBot devices programmatically. By following the examples provided, you can easily integrate SwitchBot device control and monitoring into your applications. +Use `SwitchBot` for most v4 applications. Use `OpenAPIClient` only when you want direct cloud API access without the device abstraction and hybrid connection logic. diff --git a/docs/modules.html b/docs/modules.html index eaba02a1..ec56319a 100644 --- a/docs/modules.html +++ b/docs/modules.html @@ -1 +1 @@ -node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Enumerations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    LogLevel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotBLEModel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotBLEModelFriendlyName
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotBLEModelName
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotModel

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Advertising
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ErrorUtils
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ParameterChecker
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotBLE
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchbotDevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotOpenAPI
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ValidationUtils
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoAirPurifier
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoAirPurifierTable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoBlindTilt
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoBulb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoCeilingLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoContact
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoCurtain
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoHand
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoHub2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoHub3
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoHumi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoHumi2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoIOSensorTH
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoKeypad
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoLeak
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoPlugMiniJP
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoPlugMiniUS
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoPresence
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoRelaySwitch1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoRelaySwitch1PM
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoRemote
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSensorTH
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSensorTHPlus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSensorTHPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSensorTHProCO2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSmartLock
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoSmartLockPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WoStrip

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    AdvertisementData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    body
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    bodyChange
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Chars
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ColorLightServiceDataBase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deleteWebhookResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceList
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    devices
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceStatusRequest
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceWebhook
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    deviceWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ErrorObject
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    infraredRemoteList
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    irdevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    LockBaseServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    NobleTypes
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Params
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    PlugMiniServiceDataBase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    pushRequest
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    pushResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    pushResponseBody
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    queryWebhookResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Rule
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    setupWebhookResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotBLEDevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwitchBotScanner
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    TemperatureServiceDataBase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    updateWebhookResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WebhookDetail
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    webhookRequest

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Aliases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifier
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierPM25WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTablePM25WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableVOC
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableVOCStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableVOCWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierVOC
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierVOCStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierVOCWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    batteryCirculatorFan
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    batteryCirculatorFanServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    batteryCirculatorFanStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    batteryCirculatorFanWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    BLEDeviceServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    blindTilt
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    blindTiltServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    blindTiltStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    blindTiltWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    bot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    botServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    botStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    botWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightProStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightProWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    circulatorFanStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    circulatorFanWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    colorBulb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    colorBulbServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    colorBulbStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    colorBulbWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    commandType
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    contactSensor
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    contactSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    contactSensorStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    contactSensorWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtain
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtain3
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtain3ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtain3WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtainServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtainStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtainWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    floorCleaningRobotS10
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    floorCleaningRobotS10Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    floorCleaningRobotS10WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hub2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hub2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hub2Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hub2WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hub3ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifier
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifier2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifier2Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifier2WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifierStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifierWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    IndoorCam
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    indoorCameraWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypad
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypadDetectorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypadTouch
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypadTouchWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypadWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lock
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockProStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockProWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    MacAddress
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meter
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPlus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPlusServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPlusStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPlusWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProCO2ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProCO2Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProCO2WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterProWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    motionSensor
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    motionSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    motionSensorStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    motionSensorWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    onadvertisement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ondiscover
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    outdoorMeter
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    outdoorMeterServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    outdoorMeterStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    outdoorMeterWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    pantiltCam
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    pantiltCam2k
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    panTiltCamWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plug
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMini
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMiniJPServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMiniJPWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMiniStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMiniUSServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugMiniUSWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    presenceSensor
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    presenceSensorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    presenceSensorStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    presenceSensorWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1Context
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1PMContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1PMServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1PMStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1ServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    remote
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    remoteServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1Plus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1PlusStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1PlusWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1Status
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1WebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    stripLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    stripLightServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    stripLightStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    stripLightWebhookContext
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    waterLeakDetector
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    waterLeakDetectorServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    waterLeakDetectorStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    waterLeakDetectorWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Variables

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    parameterChecker
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    urls

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Functions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    updateBaseURL
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    +node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Enumerations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LogLevel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBotBLEModel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBotBLEModelName

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APIError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APINotAvailableError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLEConnection
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLENotAvailableError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLEScanner
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CommandFailedError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ConnectionTimeoutError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceManager
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceNotFoundError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceOverrideStateDuringConnection
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DiscoveryError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        OpenAPIClient
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SequenceDevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBotDevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBotError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ValidationError
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoAIHub
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoAirPurifier
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoAirPurifierPM25
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoAirPurifierTable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoArtFrame
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoBlindTilt
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoBulb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoCandleWarmerLamp
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoCeilingLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoCirculatorFan
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoClimatePanel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoContact
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoCurtain
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoFloorLamp
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoGarageDoorOpener
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHand
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHub2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHub3
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHubMiniMatter
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHumi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoHumi2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoIOSensorTH
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoKeypad
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoKeypadVision
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoKeypadVisionPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoLeak
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoPanTiltCamPlus3K
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoPlugMiniJP
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoPlugMiniUS
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoPresence
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRelaySwitch1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRelaySwitch1PM
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRelaySwitch2PM
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRemote
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRemoteWithScreen
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRGBICBulb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRGBICNeonWireRopeLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRGBICWWFloorLamp
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRGBICWWStripLight
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoRollerShade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSensorTH
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSensorTHPlus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSensorTHPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSensorTHProCO2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLock
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLockLite
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLockPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLockProWiFi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLockVision
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartLockVisionPro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoSmartThermostatRadiator
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoStrip
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoStripLight3
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuum
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumK10Plus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumK10Pro
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumK10ProCombo
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumK11Plus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumK20
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumS10
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoVacuumS20
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WoWaterDetector

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        AirPurifierCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        AirPurifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        AirPurifierStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APICommandRequest
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APICommandResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APIDevice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APIDeviceStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APIErrorResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APIResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLEAdvertisement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLEScanOptions
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BLEServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BlindTiltCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BlindTiltServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BlindTiltStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BotCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BotServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BotStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BulbCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BulbServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        BulbStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CeilingLightCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CeilingLightServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CeilingLightStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CommandResult
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ContactServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ContactStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CurtainCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CurtainExtendedInfo
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CurtainServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CurtainStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceInfo
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceListResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DeviceStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        DiscoveryOptions
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HubServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HubStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HumidifierCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HumidifierServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HumidifierStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        KeypadStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LeakServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LeakStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LockCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LockServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        LockStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        MeterServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        MeterStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        MotionServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        MotionStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PlugCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PlugServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PlugStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PresenceServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PresenceStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        RelaySwitchCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        RelaySwitchServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        RelaySwitchStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        RemoteStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SceneListResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        StripCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        StripServiceData
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        StripStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwitchBotConfig
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        VacuumCommands
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        VacuumStatus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WebhookConfig
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WebhookDetails
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WebhookQueryResponse
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WebhookSetupResponse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Aliases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ConnectionType
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PhysicalDeviceType
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        VirtualDeviceType

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Variables

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        urls

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Functions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        updateBaseURL
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/BLEDeviceServiceData.html b/docs/types/BLEDeviceServiceData.html deleted file mode 100644 index 2ab59601..00000000 --- a/docs/types/BLEDeviceServiceData.html +++ /dev/null @@ -1 +0,0 @@ -BLEDeviceServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/CommandType.html b/docs/types/CommandType.html deleted file mode 100644 index 7a6bb0ea..00000000 --- a/docs/types/CommandType.html +++ /dev/null @@ -1,2 +0,0 @@ -commandType | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias commandType

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            commandType: "command" | "customize"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Allowed command types for device control.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/ConnectionType.html b/docs/types/ConnectionType.html new file mode 100644 index 00000000..d9642e90 --- /dev/null +++ b/docs/types/ConnectionType.html @@ -0,0 +1,2 @@ +ConnectionType | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias ConnectionType

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ConnectionType: "ble" | "api" | "hybrid"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Device connection type

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/MacAddress.html b/docs/types/MacAddress.html deleted file mode 100644 index ccd9c273..00000000 --- a/docs/types/MacAddress.html +++ /dev/null @@ -1 +0,0 @@ -MacAddress | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias MacAddress

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                MacAddress: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/PhysicalDeviceType.html b/docs/types/PhysicalDeviceType.html new file mode 100644 index 00000000..643ab92a --- /dev/null +++ b/docs/types/PhysicalDeviceType.html @@ -0,0 +1,2 @@ +PhysicalDeviceType | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias PhysicalDeviceType

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PhysicalDeviceType:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Bot"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Curtain"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Curtain3"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Plug"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Plug Mini (US)"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Plug Mini (JP)"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Meter"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Meter Plus"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Meter Pro"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Meter Pro (CO2)"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Outdoor Meter"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Lock"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Lock Pro"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Keypad"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Keypad Touch"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Motion Sensor"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Contact Sensor"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Ceiling Light"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Ceiling Light Pro"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Strip Light"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Color Bulb"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Robot Vacuum Cleaner S1"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Robot Vacuum Cleaner S1 Plus"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Robot Vacuum Cleaner K10 Plus"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Humidifier"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Humidifier 2"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Blind Tilt"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Hub 2"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Hub Mini"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Hub Plus"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Remote"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Battery Circulator Fan"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Air Purifier"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Air Purifier Table"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Water Leak Detector"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Presence Sensor"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Relay Switch 1PM"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "Relay Switch 1"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | "K10+ Pro Combo"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Physical device types supported by OpenAPI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/VirtualDeviceType.html b/docs/types/VirtualDeviceType.html new file mode 100644 index 00000000..9568ba73 --- /dev/null +++ b/docs/types/VirtualDeviceType.html @@ -0,0 +1,2 @@ +VirtualDeviceType | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias VirtualDeviceType

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    VirtualDeviceType:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Air Conditioner"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "TV"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Light"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "IPTV/Streamer"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Set Top Box"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "DVD"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Fan"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Projector"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Camera"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Air Purifier"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Speaker"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Water Heater"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Vacuum Cleaner"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Others"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Virtual/Infrared device types

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/airPurifier.html b/docs/types/airPurifier.html deleted file mode 100644 index 7483deed..00000000 --- a/docs/types/airPurifier.html +++ /dev/null @@ -1 +0,0 @@ -airPurifier | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias airPurifier

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      airPurifier: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/airPurifierPM25WebhookContext.html b/docs/types/airPurifierPM25WebhookContext.html deleted file mode 100644 index e1afee92..00000000 --- a/docs/types/airPurifierPM25WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierPM25WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias airPurifierPM25WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        airPurifierPM25WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/airPurifierServiceData.html b/docs/types/airPurifierServiceData.html deleted file mode 100644 index d043657c..00000000 --- a/docs/types/airPurifierServiceData.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias airPurifierServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          airPurifierServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              aqi_level: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              child_lock: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              err_code: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              filter_element_working_time: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              isAqiValid: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              isOn: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              mode: string | null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              model: AirPurifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelFriendlyName: AirPurifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelName: AirPurifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              sequence_number: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              speed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/airPurifierStatus.html b/docs/types/airPurifierStatus.html deleted file mode 100644 index 5e114107..00000000 --- a/docs/types/airPurifierStatus.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias airPurifierStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            airPurifierStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/airPurifierTable.html b/docs/types/airPurifierTable.html deleted file mode 100644 index 46e96ea4..00000000 --- a/docs/types/airPurifierTable.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTable | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias airPurifierTable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              airPurifierTable: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/airPurifierTablePM25WebhookContext.html b/docs/types/airPurifierTablePM25WebhookContext.html deleted file mode 100644 index 1d02ced5..00000000 --- a/docs/types/airPurifierTablePM25WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTablePM25WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias airPurifierTablePM25WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                airPurifierTablePM25WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/airPurifierTableServiceData.html b/docs/types/airPurifierTableServiceData.html deleted file mode 100644 index 07d7e135..00000000 --- a/docs/types/airPurifierTableServiceData.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias airPurifierTableServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  airPurifierTableServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      aqi_level: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      child_lock: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      err_code: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      filter_element_working_time: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      isAqiValid: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      isOn: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      mode: string | null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      model: AirPurifierTable;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelFriendlyName: AirPurifierTable;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelName: AirPurifierTable;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      sequence_number: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      speed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/airPurifierTableStatus.html b/docs/types/airPurifierTableStatus.html deleted file mode 100644 index 2fe3779f..00000000 --- a/docs/types/airPurifierTableStatus.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias airPurifierTableStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierTableStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/airPurifierTableVOC.html b/docs/types/airPurifierTableVOC.html deleted file mode 100644 index a6573132..00000000 --- a/docs/types/airPurifierTableVOC.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableVOC | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias airPurifierTableVOC

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      airPurifierTableVOC: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/airPurifierTableVOCStatus.html b/docs/types/airPurifierTableVOCStatus.html deleted file mode 100644 index 72215108..00000000 --- a/docs/types/airPurifierTableVOCStatus.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableVOCStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias airPurifierTableVOCStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        airPurifierTableVOCStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/airPurifierTableVOCWebhookContext.html b/docs/types/airPurifierTableVOCWebhookContext.html deleted file mode 100644 index a79391c4..00000000 --- a/docs/types/airPurifierTableVOCWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableVOCWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias airPurifierTableVOCWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          airPurifierTableVOCWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/airPurifierTableWebhookContext.html b/docs/types/airPurifierTableWebhookContext.html deleted file mode 100644 index 2e21f64d..00000000 --- a/docs/types/airPurifierTableWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierTableWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias airPurifierTableWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            airPurifierTableWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/airPurifierVOC.html b/docs/types/airPurifierVOC.html deleted file mode 100644 index 9b2fad1a..00000000 --- a/docs/types/airPurifierVOC.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierVOC | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias airPurifierVOC

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              airPurifierVOC: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/airPurifierVOCStatus.html b/docs/types/airPurifierVOCStatus.html deleted file mode 100644 index fbcc7217..00000000 --- a/docs/types/airPurifierVOCStatus.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierVOCStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias airPurifierVOCStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                airPurifierVOCStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/airPurifierVOCWebhookContext.html b/docs/types/airPurifierVOCWebhookContext.html deleted file mode 100644 index cc190ae4..00000000 --- a/docs/types/airPurifierVOCWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierVOCWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias airPurifierVOCWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  airPurifierVOCWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/airPurifierWebhookContext.html b/docs/types/airPurifierWebhookContext.html deleted file mode 100644 index b519d9c2..00000000 --- a/docs/types/airPurifierWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -airPurifierWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias airPurifierWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    airPurifierWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        childLock: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/batteryCirculatorFan.html b/docs/types/batteryCirculatorFan.html deleted file mode 100644 index 9231db4d..00000000 --- a/docs/types/batteryCirculatorFan.html +++ /dev/null @@ -1 +0,0 @@ -batteryCirculatorFan | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias batteryCirculatorFan

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      batteryCirculatorFan: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/batteryCirculatorFanServiceData.html b/docs/types/batteryCirculatorFanServiceData.html deleted file mode 100644 index 381e5d29..00000000 --- a/docs/types/batteryCirculatorFanServiceData.html +++ /dev/null @@ -1 +0,0 @@ -batteryCirculatorFanServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias batteryCirculatorFanServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        batteryCirculatorFanServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            fanSpeed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            state: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/batteryCirculatorFanStatus.html b/docs/types/batteryCirculatorFanStatus.html deleted file mode 100644 index 2099b747..00000000 --- a/docs/types/batteryCirculatorFanStatus.html +++ /dev/null @@ -1 +0,0 @@ -batteryCirculatorFanStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias batteryCirculatorFanStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          batteryCirculatorFanStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              chargingStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              fanSpeed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              mode: "direct" | "natural" | "sleep" | "baby";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              nightStatus: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              oscillation: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              verticalOscillation: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/batteryCirculatorFanWebhookContext.html b/docs/types/batteryCirculatorFanWebhookContext.html deleted file mode 100644 index 9b9a0a28..00000000 --- a/docs/types/batteryCirculatorFanWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -batteryCirculatorFanWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias batteryCirculatorFanWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            batteryCirculatorFanWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                chargingStatus: "charging" | "uncharged";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                fanSpeed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                mode: "direct" | "natural" | "sleep" | "baby";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                nightStatus: "off" | 1 | 2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                oscillation: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                verticalOscillation: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/blindTilt.html b/docs/types/blindTilt.html deleted file mode 100644 index 9b609f5d..00000000 --- a/docs/types/blindTilt.html +++ /dev/null @@ -1 +0,0 @@ -blindTilt | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias blindTilt

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              blindTilt: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  blindTiltDevicesIds: string[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  direction: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  master: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  slidePosition: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/blindTiltServiceData.html b/docs/types/blindTiltServiceData.html deleted file mode 100644 index 0fc7bfec..00000000 --- a/docs/types/blindTiltServiceData.html +++ /dev/null @@ -1 +0,0 @@ -blindTiltServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias blindTiltServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                blindTiltServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    calibration: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    inMotion: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    model: BlindTilt;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelFriendlyName: BlindTilt;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelName: BlindTilt;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sequenceNumber: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    tilt: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/blindTiltStatus.html b/docs/types/blindTiltStatus.html deleted file mode 100644 index 3ba1d3b5..00000000 --- a/docs/types/blindTiltStatus.html +++ /dev/null @@ -1 +0,0 @@ -blindTiltStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias blindTiltStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  blindTiltStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      direction: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      lightLevel?: "bright" | "dim";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      slidePosition: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/blindTiltWebhookContext.html b/docs/types/blindTiltWebhookContext.html deleted file mode 100644 index d998467c..00000000 --- a/docs/types/blindTiltWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -blindTiltWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias blindTiltWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    blindTiltWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        direction: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        slidePosition: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/bot.html b/docs/types/bot.html deleted file mode 100644 index 7160a6c3..00000000 --- a/docs/types/bot.html +++ /dev/null @@ -1 +0,0 @@ -bot | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias bot

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      bot: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/botServiceData.html b/docs/types/botServiceData.html deleted file mode 100644 index c1d04c81..00000000 --- a/docs/types/botServiceData.html +++ /dev/null @@ -1 +0,0 @@ -botServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias botServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        botServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: Bot;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: Bot;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: Bot;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/botStatus.html b/docs/types/botStatus.html deleted file mode 100644 index bf46f464..00000000 --- a/docs/types/botStatus.html +++ /dev/null @@ -1 +0,0 @@ -botStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias botStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          botStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              mode: "pressMode" | "switchMode" | "customizeMode";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/botWebhookContext.html b/docs/types/botWebhookContext.html deleted file mode 100644 index f621eb5a..00000000 --- a/docs/types/botWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -botWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias botWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            botWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                deviceMode: "pressMode" | "switchMode" | "customizeMode";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/ceilingLight.html b/docs/types/ceilingLight.html deleted file mode 100644 index 8a4b4e12..00000000 --- a/docs/types/ceilingLight.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLight | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias ceilingLight

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ceilingLight: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/ceilingLightPro.html b/docs/types/ceilingLightPro.html deleted file mode 100644 index 48477a4d..00000000 --- a/docs/types/ceilingLightPro.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightPro | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias ceilingLightPro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ceilingLightPro: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/ceilingLightProServiceData.html b/docs/types/ceilingLightProServiceData.html deleted file mode 100644 index 0066f350..00000000 --- a/docs/types/ceilingLightProServiceData.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightProServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias ceilingLightProServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ceilingLightProServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      blue: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      color_mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      color_temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      delay: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      green: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      loop_index: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      model: CeilingLightPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelFriendlyName: CeilingLightPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelName: CeilingLightPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      power: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      preset: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      red: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      speed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/ceilingLightProStatus.html b/docs/types/ceilingLightProStatus.html deleted file mode 100644 index 6146bff8..00000000 --- a/docs/types/ceilingLightProStatus.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightProStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias ceilingLightProStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ceilingLightProStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        power: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/ceilingLightProWebhookContext.html b/docs/types/ceilingLightProWebhookContext.html deleted file mode 100644 index 2e6c1ad4..00000000 --- a/docs/types/ceilingLightProWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightProWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias ceilingLightProWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ceilingLightProWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/ceilingLightServiceData.html b/docs/types/ceilingLightServiceData.html deleted file mode 100644 index 4846621e..00000000 --- a/docs/types/ceilingLightServiceData.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias ceilingLightServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ceilingLightServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            blue: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            color_mode: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            color_temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            delay: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            green: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            loop_index: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: CeilingLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: CeilingLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: CeilingLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            power: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            preset: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            red: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            speed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/ceilingLightStatus.html b/docs/types/ceilingLightStatus.html deleted file mode 100644 index d0ad8d3b..00000000 --- a/docs/types/ceilingLightStatus.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias ceilingLightStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ceilingLightStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              power: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/ceilingLightWebhookContext.html b/docs/types/ceilingLightWebhookContext.html deleted file mode 100644 index 9d0c04fc..00000000 --- a/docs/types/ceilingLightWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -ceilingLightWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias ceilingLightWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ceilingLightWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/circulatorFanStatus.html b/docs/types/circulatorFanStatus.html deleted file mode 100644 index ecd4cc02..00000000 --- a/docs/types/circulatorFanStatus.html +++ /dev/null @@ -1 +0,0 @@ -circulatorFanStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias circulatorFanStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              circulatorFanStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  fanSpeed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  mode: "direct" | "natural" | "sleep" | "baby";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  nightStatus: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  oscillation: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  verticalOscillation: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/circulatorFanWebhookContext.html b/docs/types/circulatorFanWebhookContext.html deleted file mode 100644 index 958a7aba..00000000 --- a/docs/types/circulatorFanWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -circulatorFanWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias circulatorFanWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                circulatorFanWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    fanSpeed: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    mode: "direct" | "natural" | "sleep" | "baby";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    nightStatus: "off" | 1 | 2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    oscillation: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    verticalOscillation: "on" | "off";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/colorBulb.html b/docs/types/colorBulb.html deleted file mode 100644 index 374d1daa..00000000 --- a/docs/types/colorBulb.html +++ /dev/null @@ -1 +0,0 @@ -colorBulb | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias colorBulb

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  colorBulb: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/colorBulbServiceData.html b/docs/types/colorBulbServiceData.html deleted file mode 100644 index 7fd5dec1..00000000 --- a/docs/types/colorBulbServiceData.html +++ /dev/null @@ -1 +0,0 @@ -colorBulbServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias colorBulbServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    colorBulbServiceData: ColorLightServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        model: ColorBulb;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelFriendlyName: ColorBulb;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelName: ColorBulb;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/colorBulbStatus.html b/docs/types/colorBulbStatus.html deleted file mode 100644 index 64c2ffcc..00000000 --- a/docs/types/colorBulbStatus.html +++ /dev/null @@ -1 +0,0 @@ -colorBulbStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias colorBulbStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      colorBulbStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          color: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/colorBulbWebhookContext.html b/docs/types/colorBulbWebhookContext.html deleted file mode 100644 index 846b1844..00000000 --- a/docs/types/colorBulbWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -colorBulbWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias colorBulbWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        colorBulbWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            color: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            colorTemperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/contactSensor.html b/docs/types/contactSensor.html deleted file mode 100644 index ffe92e78..00000000 --- a/docs/types/contactSensor.html +++ /dev/null @@ -1 +0,0 @@ -contactSensor | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias contactSensor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          contactSensor: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/contactSensorServiceData.html b/docs/types/contactSensorServiceData.html deleted file mode 100644 index 3ef5f10c..00000000 --- a/docs/types/contactSensorServiceData.html +++ /dev/null @@ -1 +0,0 @@ -contactSensorServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias contactSensorServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            contactSensorServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                button_count: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                contact_open: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                contact_timeout: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                doorState: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lightLevel: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                model: ContactSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelFriendlyName: ContactSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelName: ContactSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                movement: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                tested: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/contactSensorStatus.html b/docs/types/contactSensorStatus.html deleted file mode 100644 index 62b44ef0..00000000 --- a/docs/types/contactSensorStatus.html +++ /dev/null @@ -1 +0,0 @@ -contactSensorStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias contactSensorStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              contactSensorStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  brightness: "bright" | "dim";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  openState: "open" | "close" | "timeOutNotClose";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/contactSensorWebhookContext.html b/docs/types/contactSensorWebhookContext.html deleted file mode 100644 index f6c60949..00000000 --- a/docs/types/contactSensorWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -contactSensorWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias contactSensorWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                contactSensorWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    brightness: "dim" | "bright";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    detectionState: "NOT_DETECTED" | "DETECTED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    doorMode: "IN_DOOR" | "OUT_DOOR";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    openState: "open" | "close" | "timeOutNotClose";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/curtain.html b/docs/types/curtain.html deleted file mode 100644 index aadc7210..00000000 --- a/docs/types/curtain.html +++ /dev/null @@ -1 +0,0 @@ -curtain | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias curtain

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  curtain: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      curtainDevicesIds: string[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      master: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      openDirection: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/curtain3.html b/docs/types/curtain3.html deleted file mode 100644 index d40d3321..00000000 --- a/docs/types/curtain3.html +++ /dev/null @@ -1 +0,0 @@ -curtain3 | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias curtain3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    curtain3: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        curtainDevicesIds: string[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        master: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        openDirection?: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/curtain3ServiceData.html b/docs/types/curtain3ServiceData.html deleted file mode 100644 index c45d1bee..00000000 --- a/docs/types/curtain3ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -curtain3ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias curtain3ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      curtain3ServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          calibration: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          deviceChain: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          inMotion: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          model: Curtain3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelFriendlyName: Curtain3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelName: Curtain3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          position: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/curtain3WebhookContext.html b/docs/types/curtain3WebhookContext.html deleted file mode 100644 index 1b0ac020..00000000 --- a/docs/types/curtain3WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -curtain3WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias curtain3WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        curtain3WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            slidePosition: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/curtainServiceData.html b/docs/types/curtainServiceData.html deleted file mode 100644 index 017c409c..00000000 --- a/docs/types/curtainServiceData.html +++ /dev/null @@ -1 +0,0 @@ -curtainServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias curtainServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          curtainServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              calibration: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              deviceChain: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              inMotion: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              model: Curtain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelFriendlyName: Curtain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelName: Curtain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              position: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/curtainStatus.html b/docs/types/curtainStatus.html deleted file mode 100644 index 2c9cd185..00000000 --- a/docs/types/curtainStatus.html +++ /dev/null @@ -1 +0,0 @@ -curtainStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias curtainStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            curtainStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lightLevel?: "bright" | "dim";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                moving: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                slidePosition: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/curtainWebhookContext.html b/docs/types/curtainWebhookContext.html deleted file mode 100644 index bc3c718d..00000000 --- a/docs/types/curtainWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -curtainWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias curtainWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              curtainWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  calibrate: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  slidePosition: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/floorCleaningRobotS10.html b/docs/types/floorCleaningRobotS10.html deleted file mode 100644 index 77a05334..00000000 --- a/docs/types/floorCleaningRobotS10.html +++ /dev/null @@ -1 +0,0 @@ -floorCleaningRobotS10 | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias floorCleaningRobotS10

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                floorCleaningRobotS10: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/floorCleaningRobotS10Status.html b/docs/types/floorCleaningRobotS10Status.html deleted file mode 100644 index b42f2735..00000000 --- a/docs/types/floorCleaningRobotS10Status.html +++ /dev/null @@ -1 +0,0 @@ -floorCleaningRobotS10Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias floorCleaningRobotS10Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  floorCleaningRobotS10Status: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      onlineStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      taskType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      waterBaseBattery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      workingStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/floorCleaningRobotS10WebhookContext.html b/docs/types/floorCleaningRobotS10WebhookContext.html deleted file mode 100644 index 5a425efb..00000000 --- a/docs/types/floorCleaningRobotS10WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -floorCleaningRobotS10WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias floorCleaningRobotS10WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    floorCleaningRobotS10WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        onlineStatus: "online" | "offline";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        taskType:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "standBy"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "explore"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "cleanAll"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "cleanArea"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "cleanRoom"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "fillWater"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "deepWashing"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "backToCharge"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "markingWaterBase"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "drying"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "collectDust"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "remoteControl"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "cleanWithExplorer"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "fillWaterForHumi"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "markingHumi";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        waterBaseBattery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        workingStatus: | "Standby"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Clearing"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Paused"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "GotoChargeBase"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Charging"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "ChargeDone"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "Dormant"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "InTrouble"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "InRemoteControl"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | "InDustCollecting";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/hub2.html b/docs/types/hub2.html deleted file mode 100644 index 85cac518..00000000 --- a/docs/types/hub2.html +++ /dev/null @@ -1 +0,0 @@ -hub2 | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias hub2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      hub2: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/hub2ServiceData.html b/docs/types/hub2ServiceData.html deleted file mode 100644 index 94403eab..00000000 --- a/docs/types/hub2ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -hub2ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias hub2ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        hub2ServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            celsius: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            fahrenheit: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            fahrenheit_mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: Hub2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: Hub2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: Hub2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/hub2Status.html b/docs/types/hub2Status.html deleted file mode 100644 index 1bf3d93e..00000000 --- a/docs/types/hub2Status.html +++ /dev/null @@ -1 +0,0 @@ -hub2Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias hub2Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          hub2Status: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/hub2WebhookContext.html b/docs/types/hub2WebhookContext.html deleted file mode 100644 index b7767f2e..00000000 --- a/docs/types/hub2WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -hub2WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias hub2WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            hub2WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/hub3ServiceData.html b/docs/types/hub3ServiceData.html deleted file mode 100644 index cc6aecff..00000000 --- a/docs/types/hub3ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -hub3ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias hub3ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              hub3ServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  celsius: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  fahrenheit: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  fahrenheit_mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  model: Hub3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelFriendlyName: Hub3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelName: Hub3;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/humidifier.html b/docs/types/humidifier.html deleted file mode 100644 index 3d546781..00000000 --- a/docs/types/humidifier.html +++ /dev/null @@ -1 +0,0 @@ -humidifier | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias humidifier

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                humidifier: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/humidifier2ServiceData.html b/docs/types/humidifier2ServiceData.html deleted file mode 100644 index 5c5a06e2..00000000 --- a/docs/types/humidifier2ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -humidifier2ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias humidifier2ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  humidifier2ServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      autoMode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      childLock: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      filterAlert: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      filterMissing: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      filterRunTime: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      model: Humidifier2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelFriendlyName: Humidifier2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelName: Humidifier2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      onState: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      overHumidifyProtection: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      percentage: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      tankRemoved: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      tiltedAlert: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      waterLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/humidifier2Status.html b/docs/types/humidifier2Status.html deleted file mode 100644 index e5d16f49..00000000 --- a/docs/types/humidifier2Status.html +++ /dev/null @@ -1 +0,0 @@ -humidifier2Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias humidifier2Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidifier2Status: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        auto: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        childLock: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        lackWater: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        nebulizationEfficiency: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        sound: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/humidifier2WebhookContext.html b/docs/types/humidifier2WebhookContext.html deleted file mode 100644 index 65d539ed..00000000 --- a/docs/types/humidifier2WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -humidifier2WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias humidifier2WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      humidifier2WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/humidifierServiceData.html b/docs/types/humidifierServiceData.html deleted file mode 100644 index c4fa5a0b..00000000 --- a/docs/types/humidifierServiceData.html +++ /dev/null @@ -1 +0,0 @@ -humidifierServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias humidifierServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        humidifierServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            autoMode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: Humidifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: Humidifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: Humidifier;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            onState: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            percentage: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/humidifierStatus.html b/docs/types/humidifierStatus.html deleted file mode 100644 index d2396da3..00000000 --- a/docs/types/humidifierStatus.html +++ /dev/null @@ -1 +0,0 @@ -humidifierStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias humidifierStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          humidifierStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              auto: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              childLock: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lackWater: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              nebulizationEfficiency: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              sound: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/humidifierWebhookContext.html b/docs/types/humidifierWebhookContext.html deleted file mode 100644 index 23dbf255..00000000 --- a/docs/types/humidifierWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -humidifierWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias humidifierWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            humidifierWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/indoorCam.html b/docs/types/indoorCam.html deleted file mode 100644 index afa45624..00000000 --- a/docs/types/indoorCam.html +++ /dev/null @@ -1 +0,0 @@ -IndoorCam | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias IndoorCam

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              IndoorCam: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/indoorCameraWebhookContext.html b/docs/types/indoorCameraWebhookContext.html deleted file mode 100644 index 45868671..00000000 --- a/docs/types/indoorCameraWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -indoorCameraWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias indoorCameraWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                indoorCameraWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    detectionState: "DETECTED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/keypad.html b/docs/types/keypad.html deleted file mode 100644 index 6401d8da..00000000 --- a/docs/types/keypad.html +++ /dev/null @@ -1 +0,0 @@ -keypad | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias keypad

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  keypad: device & { keyList: keyList; lockDeviceId: string; remoteType: string }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/keypadDetectorServiceData.html b/docs/types/keypadDetectorServiceData.html deleted file mode 100644 index 0d7a28f5..00000000 --- a/docs/types/keypadDetectorServiceData.html +++ /dev/null @@ -1 +0,0 @@ -keypadDetectorServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias keypadDetectorServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    keypadDetectorServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        event: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        low_battery: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        model: Keypad;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelFriendlyName: Keypad;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelName: Keypad;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        tampered: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/keypadTouch.html b/docs/types/keypadTouch.html deleted file mode 100644 index 216d1555..00000000 --- a/docs/types/keypadTouch.html +++ /dev/null @@ -1 +0,0 @@ -keypadTouch | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias keypadTouch

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      keypadTouch: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          keyList: keyList;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          lockDeviceId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          remoteType: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/keypadTouchWebhookContext.html b/docs/types/keypadTouchWebhookContext.html deleted file mode 100644 index bf2f749e..00000000 --- a/docs/types/keypadTouchWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -keypadTouchWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias keypadTouchWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        keypadTouchWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            commandId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            eventName: "createKey" | "deleteKey";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            result: "success" | "failed" | "timeout";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/keypadWebhookContext.html b/docs/types/keypadWebhookContext.html deleted file mode 100644 index 86848ac9..00000000 --- a/docs/types/keypadWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -keypadWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias keypadWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          keypadWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              commandId: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              eventName: "createKey" | "deleteKey";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              result: "success" | "failed" | "timeout";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/lock.html b/docs/types/lock.html deleted file mode 100644 index ff984611..00000000 --- a/docs/types/lock.html +++ /dev/null @@ -1 +0,0 @@ -lock | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias lock

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            lock: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                groupName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lockDevicesIds: string[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                master: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/lockPro.html b/docs/types/lockPro.html deleted file mode 100644 index 5d23cdb2..00000000 --- a/docs/types/lockPro.html +++ /dev/null @@ -1 +0,0 @@ -lockPro | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias lockPro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lockPro: device & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  group: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  groupName: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  lockDevicesIds: string[];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  master: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/lockProServiceData.html b/docs/types/lockProServiceData.html deleted file mode 100644 index 2eaceacd..00000000 --- a/docs/types/lockProServiceData.html +++ /dev/null @@ -1 +0,0 @@ -lockProServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias lockProServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lockProServiceData: LockBaseServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    model: LockPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelFriendlyName: LockPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelName: LockPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/lockProStatus.html b/docs/types/lockProStatus.html deleted file mode 100644 index eed0ae79..00000000 --- a/docs/types/lockProStatus.html +++ /dev/null @@ -1 +0,0 @@ -lockProStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias lockProStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  lockProStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      doorState: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      lockState: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/lockProWebhookContext.html b/docs/types/lockProWebhookContext.html deleted file mode 100644 index 2f6b9c5e..00000000 --- a/docs/types/lockProWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -lockProWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias lockProWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    lockProWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        lockState: "UNLOCKED" | "LOCKED" | "JAMMED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/lockServiceData.html b/docs/types/lockServiceData.html deleted file mode 100644 index 9a41aeca..00000000 --- a/docs/types/lockServiceData.html +++ /dev/null @@ -1 +0,0 @@ -lockServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias lockServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      lockServiceData: LockBaseServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          model: Lock;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelFriendlyName: Lock;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelName: Lock;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/lockStatus.html b/docs/types/lockStatus.html deleted file mode 100644 index 4ba2db8f..00000000 --- a/docs/types/lockStatus.html +++ /dev/null @@ -1 +0,0 @@ -lockStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias lockStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        lockStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            doorState: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            lockState: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/lockWebhookContext.html b/docs/types/lockWebhookContext.html deleted file mode 100644 index 70f1211f..00000000 --- a/docs/types/lockWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -lockWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias lockWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          lockWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lockState: "UNLOCKED" | "LOCKED" | "JAMMED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/meter.html b/docs/types/meter.html deleted file mode 100644 index fcbd8149..00000000 --- a/docs/types/meter.html +++ /dev/null @@ -1 +0,0 @@ -meter | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias meter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            meter: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/meterPlus.html b/docs/types/meterPlus.html deleted file mode 100644 index 02295b08..00000000 --- a/docs/types/meterPlus.html +++ /dev/null @@ -1 +0,0 @@ -meterPlus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias meterPlus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              meterPlus: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/meterPlusServiceData.html b/docs/types/meterPlusServiceData.html deleted file mode 100644 index 49ce02ae..00000000 --- a/docs/types/meterPlusServiceData.html +++ /dev/null @@ -1 +0,0 @@ -meterPlusServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias meterPlusServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                meterPlusServiceData: TemperatureServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    model: MeterPlus;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelFriendlyName: MeterPlus;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    modelName: MeterPlus;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/meterPlusStatus.html b/docs/types/meterPlusStatus.html deleted file mode 100644 index fa870e04..00000000 --- a/docs/types/meterPlusStatus.html +++ /dev/null @@ -1 +0,0 @@ -meterPlusStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias meterPlusStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  meterPlusStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/meterPlusWebhookContext.html b/docs/types/meterPlusWebhookContext.html deleted file mode 100644 index 8b852e52..00000000 --- a/docs/types/meterPlusWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -meterPlusWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias meterPlusWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterPlusWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/meterPro.html b/docs/types/meterPro.html deleted file mode 100644 index 1af674a4..00000000 --- a/docs/types/meterPro.html +++ /dev/null @@ -1 +0,0 @@ -meterPro | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias meterPro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      meterPro: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/meterProCO2ServiceData.html b/docs/types/meterProCO2ServiceData.html deleted file mode 100644 index 1e955cc1..00000000 --- a/docs/types/meterProCO2ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -meterProCO2ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias meterProCO2ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        meterProCO2ServiceData: TemperatureServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            co2: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: MeterProCO2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: MeterProCO2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: MeterProCO2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/meterProCO2Status.html b/docs/types/meterProCO2Status.html deleted file mode 100644 index 4e37ff2b..00000000 --- a/docs/types/meterProCO2Status.html +++ /dev/null @@ -1 +0,0 @@ -meterProCO2Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias meterProCO2Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          meterProCO2Status: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              CO2: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/meterProCO2WebhookContext.html b/docs/types/meterProCO2WebhookContext.html deleted file mode 100644 index c6fc0e65..00000000 --- a/docs/types/meterProCO2WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -meterProCO2WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias meterProCO2WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            meterProCO2WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CO2: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/meterProServiceData.html b/docs/types/meterProServiceData.html deleted file mode 100644 index 1953a3f3..00000000 --- a/docs/types/meterProServiceData.html +++ /dev/null @@ -1 +0,0 @@ -meterProServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias meterProServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              meterProServiceData: TemperatureServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  model: MeterPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelFriendlyName: MeterPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelName: MeterPro;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/meterProStatus.html b/docs/types/meterProStatus.html deleted file mode 100644 index 506761b6..00000000 --- a/docs/types/meterProStatus.html +++ /dev/null @@ -1 +0,0 @@ -meterProStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias meterProStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                meterProStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/meterProWebhookContext.html b/docs/types/meterProWebhookContext.html deleted file mode 100644 index b4d918fc..00000000 --- a/docs/types/meterProWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -meterProWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias meterProWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  meterProWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/meterServiceData.html b/docs/types/meterServiceData.html deleted file mode 100644 index 8d1a3cc2..00000000 --- a/docs/types/meterServiceData.html +++ /dev/null @@ -1 +0,0 @@ -meterServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias meterServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    meterServiceData: TemperatureServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        model: Meter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelFriendlyName: Meter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        modelName: Meter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/meterStatus.html b/docs/types/meterStatus.html deleted file mode 100644 index 3a282f97..00000000 --- a/docs/types/meterStatus.html +++ /dev/null @@ -1 +0,0 @@ -meterStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias meterStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      meterStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/meterWebhookContext.html b/docs/types/meterWebhookContext.html deleted file mode 100644 index 5ca966eb..00000000 --- a/docs/types/meterWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -meterWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias meterWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        meterWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/motionSensor.html b/docs/types/motionSensor.html deleted file mode 100644 index c91b626d..00000000 --- a/docs/types/motionSensor.html +++ /dev/null @@ -1 +0,0 @@ -motionSensor | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias motionSensor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          motionSensor: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/motionSensorServiceData.html b/docs/types/motionSensorServiceData.html deleted file mode 100644 index 31f9b847..00000000 --- a/docs/types/motionSensorServiceData.html +++ /dev/null @@ -1 +0,0 @@ -motionSensorServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias motionSensorServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            motionSensorServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                iot: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                is_light: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                led: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lightLevel: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                model: MotionSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelFriendlyName: MotionSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelName: MotionSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                movement: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                sense_distance: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                tested: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/motionSensorStatus.html b/docs/types/motionSensorStatus.html deleted file mode 100644 index 37e5fa1c..00000000 --- a/docs/types/motionSensorStatus.html +++ /dev/null @@ -1 +0,0 @@ -motionSensorStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias motionSensorStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              motionSensorStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  brightness: "bright" | "dim";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  moveDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/motionSensorWebhookContext.html b/docs/types/motionSensorWebhookContext.html deleted file mode 100644 index 77d3c13f..00000000 --- a/docs/types/motionSensorWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -motionSensorWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias motionSensorWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                motionSensorWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    detectionState: "NOT_DETECTED" | "DETECTED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/onadvertisement.html b/docs/types/onadvertisement.html deleted file mode 100644 index 075c466b..00000000 --- a/docs/types/onadvertisement.html +++ /dev/null @@ -1 +0,0 @@ -onadvertisement | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias onadvertisement

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  onadvertisement: (ad: ad) => Promise<void> | void

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Declaration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • (ad: ad): Promise<void> | void
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Parameters

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Returns Promise<void> | void

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/ondiscover.html b/docs/types/ondiscover.html deleted file mode 100644 index 7b8feac4..00000000 --- a/docs/types/ondiscover.html +++ /dev/null @@ -1 +0,0 @@ -ondiscover | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias ondiscover

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ondiscover: (device: SwitchbotDevice) => Promise<void> | void

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Declaration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/outdoorMeter.html b/docs/types/outdoorMeter.html deleted file mode 100644 index 306c7f4b..00000000 --- a/docs/types/outdoorMeter.html +++ /dev/null @@ -1 +0,0 @@ -outdoorMeter | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias outdoorMeter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      outdoorMeter: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/outdoorMeterServiceData.html b/docs/types/outdoorMeterServiceData.html deleted file mode 100644 index 3bd83154..00000000 --- a/docs/types/outdoorMeterServiceData.html +++ /dev/null @@ -1 +0,0 @@ -outdoorMeterServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias outdoorMeterServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        outdoorMeterServiceData: TemperatureServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: OutdoorMeter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: OutdoorMeter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: OutdoorMeter;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/outdoorMeterStatus.html b/docs/types/outdoorMeterStatus.html deleted file mode 100644 index eba866eb..00000000 --- a/docs/types/outdoorMeterStatus.html +++ /dev/null @@ -1 +0,0 @@ -outdoorMeterStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias outdoorMeterStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          outdoorMeterStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/outdoorMeterWebhookContext.html b/docs/types/outdoorMeterWebhookContext.html deleted file mode 100644 index 150a900f..00000000 --- a/docs/types/outdoorMeterWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -outdoorMeterWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias outdoorMeterWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            outdoorMeterWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                humidity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                scale: "CELSIUS" | "FAHRENHEIT";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                temperature: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/panTiltCamWebhookContext.html b/docs/types/panTiltCamWebhookContext.html deleted file mode 100644 index a90d3a80..00000000 --- a/docs/types/panTiltCamWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -panTiltCamWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias panTiltCamWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              panTiltCamWebhookContext: deviceWebhookContext & { detectionState: "DETECTED" }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/pantiltCam.html b/docs/types/pantiltCam.html deleted file mode 100644 index e484dc08..00000000 --- a/docs/types/pantiltCam.html +++ /dev/null @@ -1 +0,0 @@ -pantiltCam | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias pantiltCam

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                pantiltCam: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/pantiltCam2k.html b/docs/types/pantiltCam2k.html deleted file mode 100644 index 473171a5..00000000 --- a/docs/types/pantiltCam2k.html +++ /dev/null @@ -1 +0,0 @@ -pantiltCam2k | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias pantiltCam2k

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  pantiltCam2k: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/plug.html b/docs/types/plug.html deleted file mode 100644 index 8562c90b..00000000 --- a/docs/types/plug.html +++ /dev/null @@ -1 +0,0 @@ -plug | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias plug

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plug: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/plugMini.html b/docs/types/plugMini.html deleted file mode 100644 index b2d78b30..00000000 --- a/docs/types/plugMini.html +++ /dev/null @@ -1 +0,0 @@ -plugMini | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias plugMini

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      plugMini: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/plugMiniJPServiceData.html b/docs/types/plugMiniJPServiceData.html deleted file mode 100644 index 833d315c..00000000 --- a/docs/types/plugMiniJPServiceData.html +++ /dev/null @@ -1 +0,0 @@ -plugMiniJPServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias plugMiniJPServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        plugMiniJPServiceData: PlugMiniServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: PlugMiniJP;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: PlugMini;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: PlugMini;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/plugMiniJPWebhookContext.html b/docs/types/plugMiniJPWebhookContext.html deleted file mode 100644 index 2b31b7de..00000000 --- a/docs/types/plugMiniJPWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -plugMiniJPWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias plugMiniJPWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          plugMiniJPWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/plugMiniStatus.html b/docs/types/plugMiniStatus.html deleted file mode 100644 index 298a7bfa..00000000 --- a/docs/types/plugMiniStatus.html +++ /dev/null @@ -1 +0,0 @@ -plugMiniStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias plugMiniStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            plugMiniStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                electricCurrent: Float64Array;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                electricityOfDay: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                voltage: Float64Array;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                weight: Float64Array;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/plugMiniUSServiceData.html b/docs/types/plugMiniUSServiceData.html deleted file mode 100644 index 541f579b..00000000 --- a/docs/types/plugMiniUSServiceData.html +++ /dev/null @@ -1 +0,0 @@ -plugMiniUSServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias plugMiniUSServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              plugMiniUSServiceData: PlugMiniServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  model: PlugMiniUS;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelFriendlyName: PlugMini;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelName: PlugMini;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/plugMiniUSWebhookContext.html b/docs/types/plugMiniUSWebhookContext.html deleted file mode 100644 index 5946033f..00000000 --- a/docs/types/plugMiniUSWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -plugMiniUSWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias plugMiniUSWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                plugMiniUSWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/plugStatus.html b/docs/types/plugStatus.html deleted file mode 100644 index d123ac1c..00000000 --- a/docs/types/plugStatus.html +++ /dev/null @@ -1 +0,0 @@ -plugStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias plugStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  plugStatus: deviceStatus & { power: string; version: string }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/plugWebhookContext.html b/docs/types/plugWebhookContext.html deleted file mode 100644 index 35936a38..00000000 --- a/docs/types/plugWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -plugWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias plugWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    plugWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/presenceSensor.html b/docs/types/presenceSensor.html deleted file mode 100644 index 4a4665a2..00000000 --- a/docs/types/presenceSensor.html +++ /dev/null @@ -1 +0,0 @@ -presenceSensor | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias presenceSensor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      presenceSensor: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/presenceSensorServiceData.html b/docs/types/presenceSensorServiceData.html deleted file mode 100644 index 17f0e9b9..00000000 --- a/docs/types/presenceSensorServiceData.html +++ /dev/null @@ -1 +0,0 @@ -presenceSensorServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias presenceSensorServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        presenceSensorServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            adaptiveState: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery?: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            batteryRange: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ledState: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            model: PresenceSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelFriendlyName: PresenceSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            modelName: PresenceSensor;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            motionDetected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            sequenceNumber: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            triggerFlag: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/presenceSensorStatus.html b/docs/types/presenceSensorStatus.html deleted file mode 100644 index 1cf6371b..00000000 --- a/docs/types/presenceSensorStatus.html +++ /dev/null @@ -1 +0,0 @@ -presenceSensorStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias presenceSensorStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          presenceSensorStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Detected: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/presenceSensorWebhookContext.html b/docs/types/presenceSensorWebhookContext.html deleted file mode 100644 index 4801379c..00000000 --- a/docs/types/presenceSensorWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -presenceSensorWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias presenceSensorWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            presenceSensorWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                detectionState: "NOT_DETECTED" | "DETECTED";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                lightLevel: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/relaySwitch1Context.html b/docs/types/relaySwitch1Context.html deleted file mode 100644 index 210d0973..00000000 --- a/docs/types/relaySwitch1Context.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1Context | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias relaySwitch1Context

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              relaySwitch1Context: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  online: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  overTemperature: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  switchStatus: 0 | 1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/relaySwitch1PMContext.html b/docs/types/relaySwitch1PMContext.html deleted file mode 100644 index 1937d483..00000000 --- a/docs/types/relaySwitch1PMContext.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1PMContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias relaySwitch1PMContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                relaySwitch1PMContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    online: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    overload: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    overTemperature: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    switchStatus: 0 | 1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/relaySwitch1PMServiceData.html b/docs/types/relaySwitch1PMServiceData.html deleted file mode 100644 index ba3560bf..00000000 --- a/docs/types/relaySwitch1PMServiceData.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1PMServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias relaySwitch1PMServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  relaySwitch1PMServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      model: RelaySwitch1PM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelFriendlyName: RelaySwitch1PM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      modelName: RelaySwitch1PM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      power: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      sequence_number: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      voltage: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/relaySwitch1PMStatus.html b/docs/types/relaySwitch1PMStatus.html deleted file mode 100644 index 850d308a..00000000 --- a/docs/types/relaySwitch1PMStatus.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1PMStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias relaySwitch1PMStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    relaySwitch1PMStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        electricCurrent: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        power: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        switchStatus: 0 | 1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        usedElectricity: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        version: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        voltage: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/relaySwitch1ServiceData.html b/docs/types/relaySwitch1ServiceData.html deleted file mode 100644 index 56ea043c..00000000 --- a/docs/types/relaySwitch1ServiceData.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1ServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias relaySwitch1ServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      relaySwitch1ServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          mode: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          model: RelaySwitch1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelFriendlyName: RelaySwitch1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelName: RelaySwitch1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          sequence_number: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          state: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/relaySwitch1Status.html b/docs/types/relaySwitch1Status.html deleted file mode 100644 index c572227c..00000000 --- a/docs/types/relaySwitch1Status.html +++ /dev/null @@ -1 +0,0 @@ -relaySwitch1Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias relaySwitch1Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        relaySwitch1Status: deviceStatus & { switchStatus: 0 | 1; version: string }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/remote.html b/docs/types/remote.html deleted file mode 100644 index 10fb5bab..00000000 --- a/docs/types/remote.html +++ /dev/null @@ -1 +0,0 @@ -remote | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias remote

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          remote: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/remoteServiceData.html b/docs/types/remoteServiceData.html deleted file mode 100644 index c210fc6d..00000000 --- a/docs/types/remoteServiceData.html +++ /dev/null @@ -1 +0,0 @@ -remoteServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias remoteServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            remoteServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                model: Remote;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelFriendlyName: Remote;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                modelName: Remote;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/robotVacuumCleanerS1.html b/docs/types/robotVacuumCleanerS1.html deleted file mode 100644 index 13a2116f..00000000 --- a/docs/types/robotVacuumCleanerS1.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1 | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias robotVacuumCleanerS1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              robotVacuumCleanerS1: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/robotVacuumCleanerS1Plus.html b/docs/types/robotVacuumCleanerS1Plus.html deleted file mode 100644 index 83634256..00000000 --- a/docs/types/robotVacuumCleanerS1Plus.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1Plus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias robotVacuumCleanerS1Plus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                robotVacuumCleanerS1Plus: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/robotVacuumCleanerS1PlusStatus.html b/docs/types/robotVacuumCleanerS1PlusStatus.html deleted file mode 100644 index 1bbde09b..00000000 --- a/docs/types/robotVacuumCleanerS1PlusStatus.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1PlusStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias robotVacuumCleanerS1PlusStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  robotVacuumCleanerS1PlusStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      onlineStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      workingStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/robotVacuumCleanerS1PlusWebhookContext.html b/docs/types/robotVacuumCleanerS1PlusWebhookContext.html deleted file mode 100644 index e9edecbf..00000000 --- a/docs/types/robotVacuumCleanerS1PlusWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1PlusWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias robotVacuumCleanerS1PlusWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    robotVacuumCleanerS1PlusWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        onlineStatus: "online" | "offline";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        workingStatus:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "Standby"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "Clearing"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "Paused"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "GotoChargeBase"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "Charging"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "ChargeDone"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "Dormant"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "InTrouble"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "InRemoteControl"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | "InDustCollecting";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/robotVacuumCleanerS1Status.html b/docs/types/robotVacuumCleanerS1Status.html deleted file mode 100644 index ea52e936..00000000 --- a/docs/types/robotVacuumCleanerS1Status.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1Status | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias robotVacuumCleanerS1Status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      robotVacuumCleanerS1Status: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          onlineStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          workingStatus: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/robotVacuumCleanerS1WebhookContext.html b/docs/types/robotVacuumCleanerS1WebhookContext.html deleted file mode 100644 index 60461191..00000000 --- a/docs/types/robotVacuumCleanerS1WebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerS1WebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias robotVacuumCleanerS1WebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        robotVacuumCleanerS1WebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            onlineStatus: "online" | "offline";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            workingStatus:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Standby"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Clearing"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Paused"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "GotoChargeBase"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Charging"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "ChargeDone"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Dormant"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "InTrouble"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "InRemoteControl"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "InDustCollecting";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/robotVacuumCleanerServiceData.html b/docs/types/robotVacuumCleanerServiceData.html deleted file mode 100644 index 64c7f6ae..00000000 --- a/docs/types/robotVacuumCleanerServiceData.html +++ /dev/null @@ -1 +0,0 @@ -robotVacuumCleanerServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias robotVacuumCleanerServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          robotVacuumCleanerServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              model: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelFriendlyName: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              modelName: Unknown;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              state: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/types/stripLight.html b/docs/types/stripLight.html deleted file mode 100644 index d35111b3..00000000 --- a/docs/types/stripLight.html +++ /dev/null @@ -1 +0,0 @@ -stripLight | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Type Alias stripLight

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            stripLight: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/types/stripLightServiceData.html b/docs/types/stripLightServiceData.html deleted file mode 100644 index 4bd9a515..00000000 --- a/docs/types/stripLightServiceData.html +++ /dev/null @@ -1 +0,0 @@ -stripLightServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Alias stripLightServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              stripLightServiceData: ColorLightServiceDataBase & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  model: StripLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelFriendlyName: StripLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  modelName: StripLight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              diff --git a/docs/types/stripLightStatus.html b/docs/types/stripLightStatus.html deleted file mode 100644 index 3672eb61..00000000 --- a/docs/types/stripLightStatus.html +++ /dev/null @@ -1 +0,0 @@ -stripLightStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Alias stripLightStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                stripLightStatus: deviceStatus & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    color: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    power: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/docs/types/stripLightWebhookContext.html b/docs/types/stripLightWebhookContext.html deleted file mode 100644 index 231f77f2..00000000 --- a/docs/types/stripLightWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -stripLightWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Type Alias stripLightWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  stripLightWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      brightness: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      color: string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      powerState: "ON" | "OFF";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  diff --git a/docs/types/waterLeakDetector.html b/docs/types/waterLeakDetector.html deleted file mode 100644 index 329bbe81..00000000 --- a/docs/types/waterLeakDetector.html +++ /dev/null @@ -1 +0,0 @@ -waterLeakDetector | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Type Alias waterLeakDetector

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    waterLeakDetector: device
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    diff --git a/docs/types/waterLeakDetectorServiceData.html b/docs/types/waterLeakDetectorServiceData.html deleted file mode 100644 index 033fb613..00000000 --- a/docs/types/waterLeakDetectorServiceData.html +++ /dev/null @@ -1 +0,0 @@ -waterLeakDetectorServiceData | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Type Alias waterLeakDetectorServiceData

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      waterLeakDetectorServiceData: BLEServiceData & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          leak: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          low_battery: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          model: Leak;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelFriendlyName: Leak;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          modelName: Leak;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          tampered: boolean;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      diff --git a/docs/types/waterLeakDetectorStatus.html b/docs/types/waterLeakDetectorStatus.html deleted file mode 100644 index a407dc0f..00000000 --- a/docs/types/waterLeakDetectorStatus.html +++ /dev/null @@ -1 +0,0 @@ -waterLeakDetectorStatus | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Type Alias waterLeakDetectorStatus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        waterLeakDetectorStatus: deviceStatus & { battery: number; status: 0 | 1 }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        diff --git a/docs/types/waterLeakDetectorWebhookContext.html b/docs/types/waterLeakDetectorWebhookContext.html deleted file mode 100644 index 4a5fcbb3..00000000 --- a/docs/types/waterLeakDetectorWebhookContext.html +++ /dev/null @@ -1 +0,0 @@ -waterLeakDetectorWebhookContext | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Type Alias waterLeakDetectorWebhookContext

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          waterLeakDetectorWebhookContext: deviceWebhookContext & {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              battery: number;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              detectionState: 0 | 1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          diff --git a/docs/variables/parameterChecker.html b/docs/variables/parameterChecker.html deleted file mode 100644 index b6d39f97..00000000 --- a/docs/variables/parameterChecker.html +++ /dev/null @@ -1 +0,0 @@ -parameterChecker | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Variable parameterCheckerConst

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            parameterChecker: ParameterChecker = ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            diff --git a/docs/variables/urls.html b/docs/variables/urls.html index 8c741dbc..9dfa9bb6 100644 --- a/docs/variables/urls.html +++ b/docs/variables/urls.html @@ -1 +1 @@ -urls | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Variable urlsConst

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              urls: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get baseURL(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get deleteWebhook(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get devicesURL(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get queryWebhook(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get setupWebhook(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  get updateWebhook(): string;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              } = ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Type Declaration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get baseURL(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get deleteWebhook(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get devicesURL(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get queryWebhook(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get setupWebhook(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • get updateWebhook(): string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              +urls | node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              node-switchbot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Variable urlsConst

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                urls: { base: string; devices: string; scenes: string; webhook: string } = ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Type Declaration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • base: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • devices: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • scenes: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • webhook: string
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                diff --git a/eslint.config.js b/eslint.config.js index 87e504d9..a7ae989c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,22 +10,23 @@ export default antfu( }, rules: { 'curly': ['error', 'multi-line'], + 'import/order': 0, 'jsdoc/check-alignment': 'error', 'jsdoc/check-line-alignment': 'error', + 'no-undef': 0, 'perfectionist/sort-exports': 'error', 'perfectionist/sort-imports': [ 'error', { groups: [ - 'builtin-type', - 'external-type', - 'internal-type', - ['parent-type', 'sibling-type', 'index-type'], + 'type-builtin', + 'type-external', + 'type-internal', + ['type-parent', 'type-sibling', 'type-index'], 'builtin', 'external', 'internal', ['parent', 'sibling', 'index'], - 'object', 'unknown', ], order: 'asc', @@ -39,10 +40,8 @@ export default antfu( 'style/quote-props': ['error', 'consistent-as-needed'], 'test/no-only-tests': 'error', 'unicorn/no-useless-spread': 'error', - 'unused-imports/no-unused-vars': ['error', { caughtErrors: 'none' }], - 'no-new': 0, // Disable the no-new rule - 'new-cap': 0, // Disable the new-cap rule - 'no-undef': 0, // Disable the no-undef rule + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', caughtErrors: 'none' }], + 'unused-imports/no-unused-vars': 0, }, }, ) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..4ae06e90 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,140 @@ +# Examples + +This directory contains usage examples for node-switchbot v4.0.0. + +## Quick Links + +- **[basic-usage.js](basic-usage.js)** - Standard usage with BLE + API hybrid mode +- **[ble-only.js](ble-only.js)** - BLE-only mode without API credentials (Linux/macOS) +- **[api-only.js](api-only.js)** - API-only mode (works on any platform) +- **[device-control.js](device-control.js)** - Comprehensive device control examples +- **[event-handling.js](event-handling.js)** - Event listeners for discovery and commands +- **[bot-password.js](bot-password.js)** - Password-protected Bot control via BLE +- **[typescript-usage.ts](typescript-usage.ts)** - TypeScript type-safe usage example + +## Prerequisites + +### For BLE Examples + +#### macOS +- **Xcode** installed from App Store +- **Bluetooth Permissions**: System Preferences → Security & Privacy → Privacy → Bluetooth → Enable your terminal app +- @stoprocent/noble package (installed automatically) + +#### Linux +- **Linux** (Raspbian, Ubuntu, etc.) +- **Required packages** (Ubuntu/Debian): + ```bash + sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev + ``` +- **Running without sudo** (Recommended): + ```bash + sudo apt-get install libcap2-bin + sudo setcap cap_net_raw+eip $(eval readlink -f `which node`) + ``` +- @stoprocent/noble package (installed automatically) + +### For API Examples + +- **SwitchBot account** with devices registered +- **OpenAPI credentials** from SwitchBot app: + 1. Open SwitchBot app + 2. Go to Profile > Preferences + 3. Tap App Version 10 times to enable Developer Options + 4. Get Token and Secret from Developer Options + +## Environment Variables + +Create a `.env` file for your credentials: + +```bash +SWITCHBOT_TOKEN=your_token_here +SWITCHBOT_SECRET=your_secret_here +``` + +## Running Examples + +### JavaScript + +```bash +# With credentials +SWITCHBOT_TOKEN=xxx SWITCHBOT_SECRET=yyy node examples/basic-usage.js + +# BLE-only (Linux/macOS) +node examples/ble-only.js + +# API-only (any platform) +SWITCHBOT_TOKEN=xxx SWITCHBOT_SECRET=yyy node examples/api-only.js +``` + +### TypeScript + +```bash +# Install ts-node if needed +npm install -g ts-node + +# Run TypeScript example +SWITCHBOT_TOKEN=xxx SWITCHBOT_SECRET=yyy ts-node examples/typescript-usage.ts +``` + +## Device Support + +All examples work with supported SwitchBot devices: + +- **Bot** (WoHand) - Press/Switch mode control +- **Curtain** (WoCurtain) - Open/close/position control +- **Lock** (WoSmartLock, WoSmartLockPro) - Lock/unlock control +- **Meter** (WoSensorTH, Plus, Pro, ProCO2, Outdoor) - Temperature/humidity monitoring +- **Plug Mini** (US, JP, EU) - On/off/toggle control +- **Bulb** (WoBulb) - Color and brightness control +- **Strip** (WoStrip) - LED strip control +- **Ceiling Light** (WoCeilingLight) - Ceiling light control +- **Blind Tilt** (WoBlindTilt) - Blind angle control +- **Humidifier** (WoHumi, WoHumi2) - Mode and efficiency control +- **Air Purifier** (WoAirPurifier, Table) - Fan speed and mode control +- **Hub** (WoHub2, WoHub3) - Status monitoring +- **Contact** (WoContact) - Open/close sensor +- **Motion** (WoPresence) - Motion detection +- **Leak** (WoLeak) - Water leak detection +- **Relay Switch** (WoRelaySwitch1, 1PM) - Relay control +- **Remote** (WoRemote) - Remote status +- **Keypad** (WoKeypad) - Keypad status + +## Example Output + +``` +Discovering devices... +Found 5 devices + +Device: Living Room Bot (WoHand) +Device: Bedroom Curtain (WoCurtain) +Device: Front Door Lock (WoSmartLock) +Device: Kitchen Meter (WoSensorTH) +Device: Office Plug (WoPlugMiniUS) +``` + +## Troubleshooting + +### BLE Not Working + +- **macOS/Linux only**: BLE requires macOS or Linux +- **Permissions**: You may need to run with `sudo` on Linux +- **Noble error**: Ensure @stoprocent/noble is installed correctly + +### API Errors + +- **401 Unauthorized**: Check your token and secret are correct +- **404 Not Found**: Device may not be registered in your account +- **Rate Limiting**: API has rate limits, add delays between requests + +### Device Not Found + +- **BLE**: Device must be in range and powered on +- **API**: Device must be registered and have cloud service enabled + +## Need Help? + +- [Main README](../README.md) +- [BLE Documentation](../BLE.md) +- [OpenAPI Documentation](../OpenAPI.md) +- [GitHub Issues](https://github.com/OpenWonderLabs/node-switchbot/issues) diff --git a/examples/api-only.js b/examples/api-only.js new file mode 100644 index 00000000..f7ee4a48 --- /dev/null +++ b/examples/api-only.js @@ -0,0 +1,66 @@ +/** + * API-Only Example - SwitchBot v4.0.0 + * + * This example shows how to use OpenAPI without BLE. + * Works on any platform (Windows, macOS, Linux) + */ + +import process from 'node:process' + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main() { + // Create SwitchBot instance with API-only mode + const switchbot = new SwitchBot({ + token: process.env.SWITCHBOT_TOKEN || '', + secret: process.env.SWITCHBOT_SECRET || '', + enableBLE: false, // Disable BLE + logLevel: LogLevel.INFO, + }) + + try { + console.log('Fetching devices from SwitchBot API...') + + // Discover devices via API only + const devices = await switchbot.discover({ + scanBLE: false, + fetchAPI: true, + }) + + console.log(`Found ${devices.length} devices in your account`) + + for (const device of devices) { + const info = device.getInfo() + console.log(` +Device: ${info.name} + Type: ${info.deviceType} + ID: ${info.id} + Cloud Enabled: ${info.cloudServiceEnabled ? 'Yes' : 'No'} + `) + } + + // Example: Control a specific device by ID + const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') + if (curtain) { + console.log('Opening curtain...') + await curtain.open() + + // Wait a bit + await new Promise(resolve => setTimeout(resolve, 2000)) + + // Get status + const status = await curtain.getStatus() + console.log('Curtain position:', status.position, '%') + } + + // Example: Get all devices of a specific type + const bots = switchbot.devices.getByType('WoHand') + console.log(`\nFound ${bots.length} Bot(s)`) + } catch (error) { + console.error('Error:', error instanceof Error ? error.message : error) + } finally { + await switchbot.cleanup() + } +} + +main() diff --git a/examples/basic-usage.js b/examples/basic-usage.js new file mode 100644 index 00000000..196870aa --- /dev/null +++ b/examples/basic-usage.js @@ -0,0 +1,61 @@ +/** + * Basic Usage Example - SwitchBot v4.0.0 + * + * This example shows how to use the unified SwitchBot class + * with automatic BLE/API discovery and fallback. + */ + +import process from 'node:process' + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main() { + // Create SwitchBot instance with OpenAPI credentials + // BLE will be used when available, with automatic API fallback + const switchbot = new SwitchBot({ + token: process.env.SWITCHBOT_TOKEN || '', + secret: process.env.SWITCHBOT_SECRET || '', + enableBLE: true, + enableFallback: true, + logLevel: LogLevel.INFO, + }) + + try { + // Discover all devices (BLE + API) + console.log('Discovering devices...') + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10000, + }) + + console.log(`Found ${devices.length} devices`) + + // Access devices via device manager + const bot = switchbot.devices.get('YOUR_DEVICE_ID') + if (bot) { + console.log(`Device: ${bot.getName()}`) + + // Control the device (automatically uses BLE or API) + await bot.press() + console.log('Bot pressed!') + + // Get device status + const status = await bot.getStatus() + console.log('Status:', status) + } + + // List all discovered devices + const allDevices = switchbot.devices.list() + for (const device of allDevices) { + console.log(`- ${device.getName()} (${device.getDeviceType()})`) + } + } catch (error) { + console.error('Error:', error instanceof Error ? error.message : error) + } finally { + // Cleanup + await switchbot.cleanup() + } +} + +main() diff --git a/examples/ble-only.js b/examples/ble-only.js new file mode 100644 index 00000000..f2c496d1 --- /dev/null +++ b/examples/ble-only.js @@ -0,0 +1,59 @@ +/** + * BLE-Only Example - SwitchBot v4.0.0 + * + * This example shows how to use BLE without OpenAPI credentials. + * Works on macOS and Linux. + */ + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main() { + // Create SwitchBot instance in BLE-only mode + const switchbot = new SwitchBot({ + enableBLE: true, + enableFallback: false, + logLevel: LogLevel.INFO, + // No token/secret needed for BLE-only mode + }) + + if (!switchbot.isBLEAvailable()) { + console.error('BLE not available on this platform') + return + } + + try { + console.log('Scanning for BLE devices...') + + // Discover devices via BLE only + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: false, + timeout: 10000, + }) + + console.log(`Found ${devices.length} BLE devices`) + + for (const device of devices) { + const info = device.getInfo() + console.log(` +Device: ${info.name} + Type: ${info.deviceType} + MAC: ${info.mac} + Battery: ${info.battery}% + RSSI: ${info.rssi} dBm + `) + + // Example: Control a Bot + if (info.deviceType === 'WoHand') { + console.log('Pressing bot...') + await device.press() + } + } + } catch (error) { + console.error('Error:', error instanceof Error ? error.message : error) + } finally { + await switchbot.cleanup() + } +} + +main() diff --git a/examples/bot-password.js b/examples/bot-password.js new file mode 100644 index 00000000..c412226e --- /dev/null +++ b/examples/bot-password.js @@ -0,0 +1,71 @@ +// Bot Password Protection Example +// This example shows how to control password-protected SwitchBot Bots + +import process from 'node:process' + +import { SwitchBot } from 'node-switchbot' + +async function main() { + const switchbot = new SwitchBot({ + enableBLE: true, + }) + + console.log('Discovering password-protected Bots...') + + // Discover Bots over BLE only + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: false, + timeout: 5000, + deviceType: 'WoHand', + }) + + if (devices.length === 0) { + console.log('No Bots found') + await switchbot.cleanup() + return + } + + const bot = devices[0] + console.log(`Found Bot: ${bot.getId()}`) + + // Set password (4 alphanumeric characters, case-sensitive) + bot.setPassword(process.env.SWITCHBOT_BOT_PASSWORD || 'A1b2') + console.log('Password set: A1b2') + + // Check if password is configured + if (bot.hasPassword()) { + console.log('✓ Bot is password protected') + } + + // All commands now use encrypted BLE transmission + console.log('Pressing Bot (encrypted command)...') + await bot.press() + + console.log('Turning Bot ON (encrypted command)...') + await bot.turnOn() + + // Wait 2 seconds + await new Promise(resolve => setTimeout(resolve, 2000)) + + console.log('Turning Bot OFF (encrypted command)...') + await bot.turnOff() + + // Clear password if needed + console.log('\nClearing password...') + bot.clearPassword() + console.log('✓ Password cleared - Bot now uses plain commands') + + // Commands now use unencrypted transmission + await bot.press() + + // Cleanup + await switchbot.cleanup() + console.log('Done!') +} + +// Handle errors +main().catch((error) => { + console.error('Error:', error) + process.exit(1) +}) diff --git a/examples/device-control.js b/examples/device-control.js new file mode 100644 index 00000000..68ea11d7 --- /dev/null +++ b/examples/device-control.js @@ -0,0 +1,108 @@ +/** + * Device Control Examples - SwitchBot v4.0.0 + * + * This example demonstrates controlling various SwitchBot devices + */ + +import process from 'node:process' + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main() { + const switchbot = new SwitchBot({ + token: process.env.SWITCHBOT_TOKEN || '', + secret: process.env.SWITCHBOT_SECRET || '', + enableBLE: true, + enableFallback: true, + logLevel: LogLevel.INFO, + }) + + try { + // Discover all devices + await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 10000, + }) + + // Bot (WoHand) - Press/Switch mode control + const bot = switchbot.devices.get('YOUR_BOT_ID') + if (bot) { + await bot.turnOn() // Switch mode: turn on + await bot.turnOff() // Switch mode: turn off + await bot.press() // Press mode: trigger press + } + + // Curtain - Position control + const curtain = switchbot.devices.get('YOUR_CURTAIN_ID') + if (curtain) { + await curtain.open() // Fully open + await curtain.close() // Fully close + await curtain.pause() // Stop movement + await curtain.setPosition(50) // Set to 50% open + + const status = await curtain.getStatus() + console.log('Curtain position:', status.position) + } + + // Lock - Lock/Unlock control + const lock = switchbot.devices.get('YOUR_LOCK_ID') + if (lock) { + await lock.lock() // Lock the door + await lock.unlock() // Unlock the door + + const status = await lock.getStatus() + console.log('Lock state:', status.lockState) + } + + // Bulb - Color and brightness control + const bulb = switchbot.devices.get('YOUR_BULB_ID') + if (bulb) { + await bulb.turnOn() + await bulb.setBrightness(80) // 80% brightness + await bulb.setColorTemperature(4000) // 4000K + await bulb.setColor(255, 0, 0) // Red color + await bulb.turnOff() + } + + // Plug - On/Off/Toggle + const plug = switchbot.devices.get('YOUR_PLUG_ID') + if (plug) { + await plug.turnOn() + await plug.turnOff() + await plug.toggle() // Toggle current state + } + + // Meter - Read temperature/humidity + const meter = switchbot.devices.get('YOUR_METER_ID') + if (meter) { + const status = await meter.getStatus() + console.log(`Temperature: ${status.temperature}°C`) + console.log(`Humidity: ${status.humidity}%`) + } + + // Humidifier - Mode and efficiency control + const humidifier = switchbot.devices.get('YOUR_HUMIDIFIER_ID') + if (humidifier) { + await humidifier.turnOn() + await humidifier.setMode('auto') // auto, manual + await humidifier.setEfficiency(75) // target humidity level / efficiency + await humidifier.turnOff() + } + + // Air Purifier - Fan speed and mode + const purifier = switchbot.devices.get('YOUR_PURIFIER_ID') + if (purifier) { + await purifier.turnOn() + await purifier.setMode('auto') // auto, manual, sleep + await purifier.setFanSpeed(3) // 1-4 + await purifier.turnOff() + } + } catch (error) { + console.error('Error:', error instanceof Error ? error.message : error) + } finally { + await switchbot.cleanup() + } +} + +main() diff --git a/examples/event-handling.js b/examples/event-handling.js new file mode 100644 index 00000000..d88517cb --- /dev/null +++ b/examples/event-handling.js @@ -0,0 +1,76 @@ +/** + * Event Handling Example - SwitchBot v4.0.0 + * + * This example shows how to listen to events during discovery and operation + */ + +import process from 'node:process' + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main() { + const switchbot = new SwitchBot({ + token: process.env.SWITCHBOT_TOKEN || '', + secret: process.env.SWITCHBOT_SECRET || '', + enableBLE: true, + logLevel: LogLevel.WARN, + }) + + // Listen for device discovery events + switchbot.on('device-discovered', (device) => { + const info = device.getInfo() + console.log(`✓ Discovered: ${info.name} (${info.deviceType})`) + + // Listen for command events on each device + device.on('command', (event) => { + console.log(` → Command via ${event.type}: ${event.success ? 'success' : 'failed'}`) + }) + + // Listen for errors on each device + device.on('error', (event) => { + console.error(` ✗ Error via ${event.type}:`, event.error.message) + }) + }) + + // Listen for errors during discovery + switchbot.on('error', (error) => { + console.error('SwitchBot error:', error.message) + }) + + try { + console.log('Starting discovery...') + + // Start discovery + const devices = await switchbot.discover({ + scanBLE: true, + fetchAPI: true, + timeout: 15000, + }) + + console.log(`\nDiscovery complete: ${devices.length} devices found\n`) + + // Test commands and observe events + for (const device of devices) { + const type = device.getDeviceType() + + console.log(`Testing ${device.getName()}...`) + + try { + if (type === 'WoHand') { + await device.press() + } else if (type === 'WoCurtain') { + const status = await device.getStatus() + console.log(` Current position: ${status.position}%`) + } + } catch { + // Already logged via event listener + } + } + } catch (error) { + console.error('Discovery error:', error instanceof Error ? error.message : error) + } finally { + await switchbot.cleanup() + } +} + +main() diff --git a/examples/typescript-usage.ts b/examples/typescript-usage.ts new file mode 100644 index 00000000..f23e7a6d --- /dev/null +++ b/examples/typescript-usage.ts @@ -0,0 +1,95 @@ +/** + * TypeScript Usage Example - SwitchBot v4.0.0 + * + * This example demonstrates type-safe usage with TypeScript + */ + +import type { BotStatus, CurtainStatus, LockStatus, MeterStatus, SwitchBotConfig, SwitchBotDevice } from 'node-switchbot' + +import process from 'node:process' + +import { LogLevel, SwitchBot } from 'node-switchbot' + +async function main(): Promise { + // Type-safe configuration + const config: SwitchBotConfig = { + token: process.env.SWITCHBOT_TOKEN || '', + secret: process.env.SWITCHBOT_SECRET || '', + enableBLE: true, + enableFallback: true, + logLevel: LogLevel.INFO, + } + + const switchbot = new SwitchBot(config) + + try { + // Discover with type-safe options + const devices = await switchbot.discover({ scanBLE: true, fetchAPI: true, timeout: 10000 }) + + console.log(`Found ${devices.length} devices`) + + // Type-safe device access + for (const device of devices) { + const deviceType = device.getDeviceType() + const deviceName = device.getName() + + console.log(`\nDevice: ${deviceName} (${deviceType})`) + + // Type-specific status handling + switch (deviceType) { + case 'WoHand': { + const status = await device.getStatus() as BotStatus + console.log(` Power: ${status.power}`) + console.log(` Battery: ${status.battery}%`) + break + } + + case 'WoCurtain': { + const status = await device.getStatus() as CurtainStatus + console.log(` Position: ${status.position}%`) + console.log(` Moving: ${status.moving ? 'yes' : 'no'}`) + console.log(` Battery: ${status.battery}%`) + break + } + + case 'WoSmartLock': { + const status = await device.getStatus() as LockStatus + console.log(` Lock State: ${status.lockState}`) + console.log(` Door State: ${status.doorState || 'unknown'}`) + console.log(` Battery: ${status.battery}%`) + break + } + + case 'WoSensorTH': { + const status = await device.getStatus() as MeterStatus + console.log(` Temperature: ${status.temperature}°C`) + console.log(` Humidity: ${status.humidity}%`) + console.log(` Battery: ${status.battery}%`) + break + } + + default: + console.log(' (Status not handled in this example)') + } + } + + // Type-safe device filtering + const allDevices = switchbot.devices.list() + const bots = allDevices.filter((d: SwitchBotDevice) => d.getDeviceType() === 'WoHand') + const curtains = allDevices.filter((d: SwitchBotDevice) => d.getDeviceType() === 'WoCurtain') + + console.log(`\nSummary:`) + console.log(` Bots: ${bots.length}`) + console.log(` Curtains: ${curtains.length}`) + } catch (error) { + if (error instanceof Error) { + console.error('Error:', error.message) + } else { + console.error('Unknown error:', error) + } + } finally { + await switchbot.cleanup() + } +} + +main().catch(console.error) diff --git a/package-lock.json b/package-lock.json index 2f7b19c8..305789ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,122 +1,100 @@ { "name": "node-switchbot", - "version": "3.6.6", + "version": "4.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "node-switchbot", - "version": "3.6.5", + "version": "4.0.0", "license": "MIT", "dependencies": { - "@stoprocent/noble": "^2.3.14", - "async-mutex": "^0.5.0", - "undici": "^7.15.0" + "@stoprocent/noble": "^2.4.0", + "undici": "^8.0.2" }, "devDependencies": { - "@antfu/eslint-config": "^5.2.1", - "@types/aes-js": "^3.1.4", - "@types/debug": "^4.1.12", - "@types/fs-extra": "^11.0.4", - "@types/mdast": "^4.0.4", - "@types/node": "^24.3.0", - "@types/semver": "^7.7.0", - "@types/source-map-support": "^0.5.10", - "@vitest/coverage-v8": "^3.2.4", - "eslint": "^9.34.0", - "eslint-plugin-format": "^1.0.1", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-import-x": "^4.16.1", - "nodemon": "^3.1.10", + "@antfu/eslint-config": "^8.1.1", + "@types/node": "^25.6.0", + "@vitest/coverage-v8": "^4.1.4", + "eslint": "^10.2.0", + "eslint-plugin-format": "^2.0.1", + "eslint-plugin-perfectionist": "^5.8.0", "shx": "^0.4.0", - "ts-node": "^10.9.2", - "typedoc": "^0.28.11", - "typescript": "^5.9.2", - "vitest": "^3.2.4" + "typedoc": "^0.28.18", + "typescript": "^6.0.2", + "vitest": "^4.1.4" }, "engines": { "node": "^20 || ^22 || ^24" }, "optionalDependencies": { - "@stoprocent/bluetooth-hci-socket": "^2.2.3" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@stoprocent/bluetooth-hci-socket": "^2.2.5" } }, "node_modules/@antfu/eslint-config": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-5.2.1.tgz", - "integrity": "sha512-EG/5kwDci1PFKSwAPMEMHDA/VYJFn0TAqwXLdnmE7zuFcaug3EGih7UOWmapMfL59Hqq6jbomaUHN31aVnL8NA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-8.1.1.tgz", + "integrity": "sha512-y5/eAKlJUbQpeES2Pnb0i/VgbmqQ+srHJJNqbTKEBsxdLy3h1BqdS00zDpE+YeP71EWmlYJSTUhcJg4n4yMeAQ==", "dev": true, "license": "MIT", "dependencies": { "@antfu/install-pkg": "^1.1.0", - "@clack/prompts": "^0.11.0", - "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0", - "@eslint/markdown": "^7.1.0", - "@stylistic/eslint-plugin": "^5.2.3", - "@typescript-eslint/eslint-plugin": "^8.39.0", - "@typescript-eslint/parser": "^8.39.0", - "@vitest/eslint-plugin": "^1.3.4", - "ansis": "^4.1.0", - "cac": "^6.7.14", - "eslint-config-flat-gitignore": "^2.1.0", - "eslint-flat-config-utils": "^2.1.1", + "@clack/prompts": "^1.2.0", + "@e18e/eslint-plugin": "^0.3.0", + "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1", + "@eslint/markdown": "^8.0.1", + "@stylistic/eslint-plugin": "^5.10.0", + "@typescript-eslint/eslint-plugin": "^8.58.1", + "@typescript-eslint/parser": "^8.58.1", + "@vitest/eslint-plugin": "^1.6.14", + "ansis": "^4.2.0", + "cac": "^7.0.0", + "eslint-config-flat-gitignore": "^2.3.0", + "eslint-flat-config-utils": "^3.1.0", "eslint-merge-processors": "^2.0.0", - "eslint-plugin-antfu": "^3.1.1", - "eslint-plugin-command": "^3.3.1", - "eslint-plugin-import-lite": "^0.3.0", - "eslint-plugin-jsdoc": "^52.0.4", - "eslint-plugin-jsonc": "^2.20.1", - "eslint-plugin-n": "^17.21.3", + "eslint-plugin-antfu": "^3.2.2", + "eslint-plugin-command": "^3.5.2", + "eslint-plugin-import-lite": "^0.6.0", + "eslint-plugin-jsdoc": "^62.9.0", + "eslint-plugin-jsonc": "^3.1.2", + "eslint-plugin-n": "^17.24.0", "eslint-plugin-no-only-tests": "^3.3.0", - "eslint-plugin-perfectionist": "^4.15.0", - "eslint-plugin-pnpm": "^1.1.0", - "eslint-plugin-regexp": "^2.10.0", - "eslint-plugin-toml": "^0.12.0", - "eslint-plugin-unicorn": "^60.0.0", - "eslint-plugin-unused-imports": "^4.1.4", - "eslint-plugin-vue": "^10.4.0", - "eslint-plugin-yml": "^1.18.0", + "eslint-plugin-perfectionist": "^5.8.0", + "eslint-plugin-pnpm": "^1.6.0", + "eslint-plugin-regexp": "^3.1.0", + "eslint-plugin-toml": "^1.3.1", + "eslint-plugin-unicorn": "^64.0.0", + "eslint-plugin-unused-imports": "^4.4.1", + "eslint-plugin-vue": "^10.8.0", + "eslint-plugin-yml": "^3.3.1", "eslint-processor-vue-blocks": "^2.0.0", - "globals": "^16.3.0", - "jsonc-eslint-parser": "^2.4.0", - "local-pkg": "^1.1.1", + "globals": "^17.4.0", + "local-pkg": "^1.1.2", "parse-gitignore": "^2.0.0", - "toml-eslint-parser": "^0.10.0", - "vue-eslint-parser": "^10.2.0", - "yaml-eslint-parser": "^1.3.0" + "toml-eslint-parser": "^1.0.3", + "vue-eslint-parser": "^10.4.0", + "yaml-eslint-parser": "^2.0.0" }, "bin": { - "eslint-config": "bin/index.js" + "eslint-config": "bin/index.mjs" }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "@eslint-react/eslint-plugin": "^1.38.4", - "@next/eslint-plugin-next": "^15.4.0-canary.115", + "@angular-eslint/eslint-plugin": "^21.1.0", + "@angular-eslint/eslint-plugin-template": "^21.1.0", + "@angular-eslint/template-parser": "^21.1.0", + "@eslint-react/eslint-plugin": "^3.0.0", + "@next/eslint-plugin-next": ">=15.0.0", "@prettier/plugin-xml": "^3.4.1", "@unocss/eslint-plugin": ">=0.50.0", "astro-eslint-parser": "^1.0.2", - "eslint": "^9.10.0", + "eslint": "^9.10.0 || ^10.0.0", "eslint-plugin-astro": "^1.2.0", "eslint-plugin-format": ">=0.1.0", "eslint-plugin-jsx-a11y": ">=6.10.2", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.19", + "eslint-plugin-react-refresh": "^0.5.0", "eslint-plugin-solid": "^0.14.3", "eslint-plugin-svelte": ">=2.35.1", "eslint-plugin-vuejs-accessibility": "^2.4.1", @@ -125,6 +103,15 @@ "svelte-eslint-parser": ">=0.37.0" }, "peerDependenciesMeta": { + "@angular-eslint/eslint-plugin": { + "optional": true + }, + "@angular-eslint/eslint-plugin-template": { + "optional": true + }, + "@angular-eslint/template-parser": { + "optional": true + }, "@eslint-react/eslint-plugin": { "optional": true }, @@ -149,9 +136,6 @@ "eslint-plugin-jsx-a11y": { "optional": true }, - "eslint-plugin-react-hooks": { - "optional": true - }, "eslint-plugin-react-refresh": { "optional": true }, @@ -175,50 +159,245 @@ } } }, - "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-unused-imports": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", - "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.1.tgz", + "integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/type-utils": "8.58.1", + "@typescript-eslint/utils": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", - "eslint": "^9.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^8.58.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/parser": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.1.tgz", + "integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", + "debug": "^4.4.3" }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-vue": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.4.0.tgz", - "integrity": "sha512-K6tP0dW8FJVZLQxa2S7LcE1lLw3X8VvB3t887Q6CLrFVxHYBXGANbXvwNzYIu6Ughx1bSJ5BDT0YB3ybPT39lw==", + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/project-service": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", + "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.3", - "xml-name-validator": "^4.0.0" + "@typescript-eslint/tsconfig-utils": "^8.58.1", + "@typescript-eslint/types": "^8.58.1", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "vue-eslint-parser": "^10.0.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/scope-manager": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", + "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", + "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/types": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", + "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", + "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.58.1", + "@typescript-eslint/tsconfig-utils": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/utils": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", + "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", + "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@vitest/eslint-plugin": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.15.tgz", + "integrity": "sha512-dTMjrdngmcB+DxomlKQ+SUubCTvd0m2hQQFpv5sx+GRodmeoxr2PVbphk57SVp250vpxphk9Ccwyv6fQ6+2gkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "^8.58.0", + "@typescript-eslint/utils": "^8.58.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "*", + "eslint": ">=8.57.0", + "typescript": ">=5.0.0", + "vitest": "*" }, "peerDependenciesMeta": { - "@typescript-eslint/parser": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vitest": { "optional": true } } }, + "node_modules/@antfu/eslint-config/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@antfu/install-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", @@ -234,9 +413,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -244,9 +423,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -254,13 +433,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -270,14 +449,14 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -294,89 +473,88 @@ } }, "node_modules/@clack/core": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", - "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.2.0.tgz", + "integrity": "sha512-qfxof/3T3t9DPU/Rj3OmcFyZInceqj/NVtO9rwIuJqCUgh32gwPjpFQQp/ben07qKlhpwq7GzfWpST4qdJ5Drg==", "dev": true, "license": "MIT", "dependencies": { - "picocolors": "^1.0.0", + "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "node_modules/@clack/prompts": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", - "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.2.0.tgz", + "integrity": "sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w==", "dev": true, "license": "MIT", "dependencies": { - "@clack/core": "0.5.0", - "picocolors": "^1.0.0", + "@clack/core": "1.2.0", + "fast-string-width": "^1.1.0", + "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@dprint/formatter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@dprint/formatter/-/formatter-0.3.0.tgz", - "integrity": "sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@dprint/formatter/-/formatter-0.5.1.tgz", + "integrity": "sha512-cdZUrm0iv/FnnY3CKE2dEcVhNEzrC551aE2h2mTFwQCRBrqyARLDnb7D+3PlXTUVp3s34ftlnGOVCmhLT9DeKA==", "dev": true, "license": "MIT" }, "node_modules/@dprint/markdown": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@dprint/markdown/-/markdown-0.17.8.tgz", - "integrity": "sha512-ukHFOg+RpG284aPdIg7iPrCYmMs3Dqy43S1ejybnwlJoFiW02b+6Bbr5cfZKFRYNP3dKGM86BqHEnMzBOyLvvA==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@dprint/markdown/-/markdown-0.21.1.tgz", + "integrity": "sha512-XbZ/R7vRrBaZFYXG6vAvLvtaMVXHu8XB+xwie7OYrG+dPoGDP8UADGirIbzUyX8TmrAZcl6QBmalipTGlpzRmQ==", "dev": true, "license": "MIT" }, "node_modules/@dprint/toml": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@dprint/toml/-/toml-0.6.4.tgz", - "integrity": "sha512-bZXIUjxr0LIuHWshZr/5mtUkOrnh0NKVZEF6ACojW5z7zkJu7s9sV2mMXm8XQDqN4cJzdHYUYzUyEGdfciaLJA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@dprint/toml/-/toml-0.7.0.tgz", + "integrity": "sha512-eFaQTcfxKHB+YyTh83x7GEv+gDPuj9q5NFOTaoj5rZmQTbj6OgjjMxUicmS1R8zYcx8YAq5oA9J3YFa5U6x2gA==", "dev": true, "license": "MIT" }, + "node_modules/@e18e/eslint-plugin": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@e18e/eslint-plugin/-/eslint-plugin-0.3.0.tgz", + "integrity": "sha512-hHgfpxsrZ2UYHcicA+tGZnmk19uJTaye9VH79O+XS8R4ona2Hx3xjhXghclNW58uXMk3xXlbYEOMr8thsoBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-plugin-depend": "^1.5.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0", + "oxlint": "^1.55.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "oxlint": { + "optional": true + } + } + }, "node_modules/@emnapi/core": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.0.4", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "dev": true, "license": "MIT", "optional": true, @@ -385,9 +563,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, @@ -396,417 +574,418 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.50.2", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.2.tgz", - "integrity": "sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==", + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.84.0.tgz", + "integrity": "sha512-0xew1CxOam0gV5OMjh2KjFQZsKL2bByX1+q4j3E73MpYIdyUxcZb/xQct9ccUb+ve5KGUYbCUxyPnYB7RbuP+w==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.6", - "@typescript-eslint/types": "^8.11.0", - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" + "@types/estree": "^1.0.8", + "@typescript-eslint/types": "^8.54.0", + "comment-parser": "1.4.5", + "esquery": "^1.7.0", + "jsdoc-type-pratt-parser": "~7.1.1" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", - "cpu": [ - "ppc64" - ], + "node_modules/@es-joy/resolve.exports": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@es-joy/resolve.exports/-/resolve.exports-1.2.0.tgz", + "integrity": "sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], "engines": { - "node": ">=18" + "node": ">=10" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", - "cpu": [ - "arm" - ], + "node_modules/@eslint-community/eslint-plugin-eslint-comments": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.7.1.tgz", + "integrity": "sha512-Ql2nJFwA8wUGpILYGOQaT1glPsmvEwE0d+a+l7AALLzQvInqdbXJdx7aSu0DpUX9dB1wMVBMhm99/++S3MdEtQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "escape-string-regexp": "^4.0.0", + "ignore": "^7.0.5" + }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", - "cpu": [ - "x64" - ], + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", - "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": ">=18" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", - "cpu": [ - "x64" - ], + "node_modules/@eslint/compat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.0.4.tgz", + "integrity": "sha512-o598tCGstJv9Kk4XapwP+oDij9HD9Qr3V37ABzTfdzVvbFciV+sfg9zSW6olj6G/IXj7p89SwSzPnZ+JUEPIPg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": "^8.40 || 9 || 10" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/config-array": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.4", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", - "cpu": [ - "x64" - ], + "node_modules/@eslint/config-helpers": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", - "cpu": [ - "arm" - ], + "node_modules/@eslint/core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/markdown": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-8.0.1.tgz", + "integrity": "sha512-WWKmld/EyNdEB8GMq7JMPX1SDWgyJAM1uhtCi5ySrqYQM4HQjmg11EX/q3ZpnpRXHfdccFtli3NBvvGaYjWyQw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" + "workspaces": [ + "examples/*" ], + "dependencies": { + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", + "github-slugger": "^2.0.0", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.1.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0", + "micromark-extension-math": "^3.1.0", + "micromark-util-normalize-identifier": "^2.0.1" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", - "cpu": [ - "ia32" - ], + "node_modules/@eslint/object-schema": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", - "cpu": [ - "loong64" - ], + "node_modules/@eslint/plugin-kit": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.1", + "levn": "^0.4.1" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", - "cpu": [ - "mips64el" - ], + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", - "cpu": [ - "riscv64" - ], + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", - "cpu": [ - "s390x" - ], + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", - "cpu": [ - "x64" - ], + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", - "cpu": [ - "x64" - ], + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", + "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", - "cpu": [ - "arm64" + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ota-meshi/ast-token-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@ota-meshi/ast-token-store/-/ast-token-store-0.3.0.tgz", + "integrity": "sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", + "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@oxfmt/binding-android-arm-eabi": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.35.0.tgz", + "integrity": "sha512-BaRKlM3DyG81y/xWTsE6gZiv89F/3pHe2BqX2H4JbiB8HNVlWWtplzgATAE5IDSdwChdeuWLDTQzJ92Lglw3ZA==", + "cpu": [ + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "openharmony" + "android" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "node_modules/@oxfmt/binding-android-arm64": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.35.0.tgz", + "integrity": "sha512-/O+EbuAJYs6nde/anv+aID6uHsGQApyE9JtYBo/79KyU8e6RBN3DMbT0ix97y1SOnCglurmL2iZ+hlohjP2PnQ==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "sunos" + "android" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "node_modules/@oxfmt/binding-darwin-arm64": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.35.0.tgz", + "integrity": "sha512-pGqRtqlNdn9d4VrmGUWVyQjkw79ryhI6je9y2jfqNUIZCfqceob+R97YYAoG7C5TFyt8ILdLVoN+L2vw/hSFyA==", "cpu": [ "arm64" ], @@ -814,33 +993,33 @@ "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", + "node_modules/@oxfmt/binding-darwin-x64": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.35.0.tgz", + "integrity": "sha512-8GmsDcSozTPjrCJeGpp+sCmS9+9V5yRrdEZ1p/sTWxPG5nYeAfSLuS0nuEYjXSO+CtdSbStIW6dxa+4NM58yRw==", "cpu": [ - "ia32" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "node_modules/@oxfmt/binding-freebsd-x64": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.35.0.tgz", + "integrity": "sha512-QyfKfTe0ytHpFKHAcHCGQEzN45QSqq1AHJOYYxQMgLM3KY4xu8OsXHpCnINjDsV4XGnQzczJDU9e04Zmd8XqIQ==", "cpu": [ "x64" ], @@ -848,5379 +1027,3635 @@ "license": "MIT", "optional": true, "os": [ - "win32" + "freebsd" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.5.0.tgz", - "integrity": "sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==", + "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.35.0.tgz", + "integrity": "sha512-u+kv3JD6P3J38oOyUaiCqgY5TNESzBRZJ5lyZQ6c2czUW2v5SIN9E/KWWa9vxoc+P8AFXQFUVrdzGy1tK+nbPQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "ignore": "^5.2.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "node_modules/@oxfmt/binding-linux-arm-musleabihf": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.35.0.tgz", + "integrity": "sha512-1NiZroCiV57I7Pf8kOH4XGR366kW5zir3VfSMBU2D0V14GpYjiYmPYFAoJboZvp8ACnZKUReWyMkNKSa5ad58A==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@oxfmt/binding-linux-arm64-gnu": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.35.0.tgz", + "integrity": "sha512-7Q0Xeg7ZnW2nxnZ4R7aF6DEbCFls4skgHZg+I63XitpNvJCbVIU8MFOTZlvZGRsY9+rPgWPQGeUpLHlyx0wvMA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "node_modules/@oxfmt/binding-linux-arm64-musl": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.35.0.tgz", + "integrity": "sha512-5Okqi+uhYFxwKz8hcnUftNNwdm8BCkf6GSCbcz9xJxYMm87k1E4p7PEmAAbhLTk7cjSdDre6TDL0pDzNX+Y22Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/compat": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.7.tgz", - "integrity": "sha512-xvv7hJE32yhegJ8xNAnb62ggiAwTYHBpUCWhRxEj/ksvgDJuSXfoDkBcRYaYNFiJ+jH0IE3K16hd+xXzhBgNbg==", + "node_modules/@oxfmt/binding-linux-ppc64-gnu": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.35.0.tgz", + "integrity": "sha512-9k66pbZQXM/lBJWys3Xbc5yhl4JexyfqkEf/tvtq8976VIJnLAAL3M127xHA3ifYSqxdVHfVGTg84eiBHCGcNw==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^9.10.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "node_modules/@oxfmt/binding-linux-riscv64-gnu": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.35.0.tgz", + "integrity": "sha512-aUcY9ofKPtjO52idT6t0SAQvEF6ctjzUQa1lLp7GDsRpSBvuTrBQGeq0rYKz3gN8dMIQ7mtMdGD9tT4LhR8jAQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@oxfmt/binding-linux-riscv64-musl": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.35.0.tgz", + "integrity": "sha512-C6yhY5Hvc2sGM+mCPek9ZLe5xRUOC/BvhAt2qIWFAeXMn4il04EYIjl3DsWiJr0xDMTJhvMOmD55xTRPlNp39w==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "node_modules/@oxfmt/binding-linux-s390x-gnu": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.35.0.tgz", + "integrity": "sha512-RG2hlvOMK4OMZpO3mt8MpxLQ0AAezlFqhn5mI/g5YrVbPFyoCv9a34AAvbSJS501ocOxlFIRcKEuw5hFvddf9g==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "node_modules/@oxfmt/binding-linux-x64-gnu": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.35.0.tgz", + "integrity": "sha512-wzmh90Pwvqj9xOKHJjkQYBpydRkaXG77ZvDz+iFDRRQpnqIEqGm5gmim2s6vnZIkDGsvKCuTdtxm0GFmBjM1+w==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "node_modules/@oxfmt/binding-linux-x64-musl": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.35.0.tgz", + "integrity": "sha512-+HCqYCJPCUy5I+b2cf+gUVaApfgtoQT3HdnSg/l7NIcLHOhKstlYaGyrFZLmUpQt4WkFbpGKZZayG6zjRU0KFA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@oxfmt/binding-openharmony-arm64": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.35.0.tgz", + "integrity": "sha512-kFYmWfR9YL78XyO5ws+1dsxNvZoD973qfVMNFOS4e9bcHXGF7DvGC2tY5UDFwyMCeB33t3sDIuGONKggnVNSJA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@oxfmt/binding-win32-arm64-msvc": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.35.0.tgz", + "integrity": "sha512-uD/NGdM65eKNCDGyTGdO8e9n3IHX+wwuorBvEYrPJXhDXL9qz6gzddmXH8EN04ejUXUujlq4FsoSeCfbg0Y+Jg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/js": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", - "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", + "node_modules/@oxfmt/binding-win32-ia32-msvc": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.35.0.tgz", + "integrity": "sha512-oSRD2k8J2uxYDEKR2nAE/YTY9PobOEnhZgCmspHu0+yBQ665yH8lFErQVSTE7fcGJmJp/cC6322/gc8VFuQf7g==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/markdown": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-7.1.0.tgz", - "integrity": "sha512-Y+X1B1j+/zupKDVJfkKc8uYMjQkGzfnd8lt7vK3y8x9Br6H5dBuhAfFrQ6ff7HAMm/1BwgecyEiRFkYCWPRxmA==", + "node_modules/@oxfmt/binding-win32-x64-msvc": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.35.0.tgz", + "integrity": "sha512-WCDJjlS95NboR0ugI2BEwzt1tYvRDorDRM9Lvctls1SLyKYuNRCyrPwp1urUPFBnwgBNn9p2/gnmo7gFMySRoQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "workspaces": [ - "examples/*" + "optional": true, + "os": [ + "win32" ], - "dependencies": { - "@eslint/core": "^0.15.1", - "@eslint/plugin-kit": "^0.3.4", - "github-slugger": "^2.0.0", - "mdast-util-from-markdown": "^2.0.2", - "mdast-util-frontmatter": "^2.0.1", - "mdast-util-gfm": "^3.1.0", - "micromark-extension-frontmatter": "^2.0.0", - "micromark-extension-gfm": "^3.0.0" - }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.2", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@gerrit0/mini-shiki": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.9.1.tgz", - "integrity": "sha512-quvtbDhNf528BkMHQQd8xGJMpmA5taDZuex/JDF8ETEjS2iypXzr1hnEUVh+lTUyffFJ0JCxysUsiuUoEGIz/Q==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@shikijs/engine-oniguruma": "^3.9.1", - "@shikijs/langs": "^3.9.1", - "@shikijs/themes": "^3.9.1", - "@shikijs/types": "^3.9.1", - "@shikijs/vscode-textmate": "^10.0.2" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", + "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=18.18.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", + "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=18.18.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", + "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", + "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", + "cpu": [ + "s390x" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", + "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", + "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", + "cpu": [ + "wasm32" + ], "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "@emnapi/core": "1.9.2", + "@emnapi/runtime": "1.9.2", + "@napi-rs/wasm-runtime": "^1.1.3" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=14.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", + "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", + "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", + "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", "dev": true, "license": "MIT" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, + "node_modules/@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" + "node": ">=12.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "node_modules/@serialport/bindings-cpp": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", + "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", + "hasInstallScript": true, "license": "MIT", + "optional": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@serialport/bindings-interface": "1.2.2", + "@serialport/parser-readline": "11.0.0", + "debug": "4.3.4", + "node-addon-api": "7.0.0", + "node-gyp-build": "4.6.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": ">=16.0.0" }, "funding": { - "url": "https://opencollective.com/unts" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", - "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", - "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", - "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", - "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", - "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", - "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", - "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", - "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", - "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", - "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", - "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", - "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", - "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", - "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", - "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", - "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", - "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", - "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", - "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", - "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@serialport/binding-mock": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", - "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@serialport/bindings-interface": "^1.2.1", - "debug": "^4.3.3" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@serialport/bindings-cpp": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", - "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "@serialport/parser-readline": "11.0.0", - "debug": "4.3.4", - "node-addon-api": "7.0.0", - "node-gyp-build": "4.6.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", - "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", - "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", - "license": "MIT", - "optional": true, - "dependencies": { - "@serialport/parser-delimiter": "11.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT", - "optional": true - }, - "node_modules/@serialport/bindings-cpp/node_modules/node-addon-api": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", - "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==", - "license": "MIT", - "optional": true - }, - "node_modules/@serialport/bindings-cpp/node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "license": "MIT", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/@serialport/bindings-interface": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", - "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", - "license": "MIT", - "optional": true, - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/@serialport/parser-byte-length": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", - "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-cctalk": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", - "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-delimiter": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", - "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-inter-byte-timeout": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", - "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", "license": "MIT", "optional": true, "engines": { "node": ">=12.0.0" }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-packet-length": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", - "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@serialport/parser-readline": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", - "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", - "license": "MIT", - "optional": true, - "dependencies": { - "@serialport/parser-delimiter": "12.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-ready": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", - "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-regex": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", - "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-slip-encoder": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", - "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-spacepacket": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", - "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/stream": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", - "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "debug": "4.3.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/stream/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@serialport/stream/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT", - "optional": true - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.9.1.tgz", - "integrity": "sha512-WPlL/xqviwS3te4unSGGGfflKsuHLMI6tPdNYvgz/IygcBT6UiwDFSzjBKyebwi5GGSlXsjjdoJLIBnAplmEZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.9.1", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.9.1.tgz", - "integrity": "sha512-Vyy2Yv9PP3Veh3VSsIvNncOR+O93wFsNYgN2B6cCCJlS7H9SKFYc55edsqernsg8WT/zam1cfB6llJsQWLnVhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.9.1" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.9.1.tgz", - "integrity": "sha512-zAykkGECNICCMXpKeVvq04yqwaSuAIvrf8MjsU5bzskfg4XreU+O0B5wdNCYRixoB9snd3YlZ373WV5E/g5T9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.9.1" - } - }, - "node_modules/@shikijs/types": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.9.1.tgz", - "integrity": "sha512-rqM3T7a0iM1oPKz9iaH/cVgNX9Vz1HERcUcXJ94/fulgVdwqfnhXzGxO4bLrAnh/o5CPLy3IcYedogfV+Ns0Qg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@stoprocent/bluetooth-hci-socket": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@stoprocent/bluetooth-hci-socket/-/bluetooth-hci-socket-2.2.4.tgz", - "integrity": "sha512-NtNhh3SfvGzxyyx0of+mixIJ7HulAdfC2jVtpzIlJi9ZxQFlxXOZnWL+KM0es6/hrT+6yFXLmfZZoTKVA/IZdw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "linux", - "android", - "freebsd", - "win32", - "darwin" - ], - "dependencies": { - "async": "^3.2.6", - "debug": "^4.3.7", - "node-addon-api": "^8.3.1", - "node-gyp-build": "^4.8.4", - "patch-package": "^8.0.0", - "serialport": "^12.0.0" - }, - "optionalDependencies": { - "usb": "^2.14.0" - } - }, - "node_modules/@stoprocent/noble": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@stoprocent/noble/-/noble-2.3.15.tgz", - "integrity": "sha512-Pcx7YAlhpyN46BfDyMdZvwoSI1rVH5C9zlGE7UwO2z/NEgmEMJOBokVfrfEV/W97vK9Hes7Lrk2pIM3ptDay9g==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.7", - "node-addon-api": "^8.1.0", - "node-gyp-build": "^4.8.1", - "patch-package": "^8.0.0" - }, - "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "@stoprocent/bluetooth-hci-socket": "^2.2.4" - } - }, - "node_modules/@stylistic/eslint-plugin": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.2.3.tgz", - "integrity": "sha512-oY7GVkJGVMI5benlBDCaRrSC1qPasafyv5dOBLLv5MTilMGnErKhO6ziEfodDDIZbo5QxPUNW360VudJOFODMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/types": "^8.38.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=9.0.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/aes-js": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/aes-js/-/aes-js-3.1.4.tgz", - "integrity": "sha512-v3D66IptpUqh+pHKVNRxY8yvp2ESSZXe0rTzsGdzUhEwag7ljVfgCllkWv2YgiYXDhWFBrEywll4A5JToyTNFA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", - "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/fs-extra": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", - "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/jsonfile": "*", - "@types/node": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", - "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~7.10.0" - } - }, - "node_modules/@types/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-tgVP2H469x9zq34Z0m/fgPewGhg/MLClalNOiPIzQlXrSS2YrKu/xCdSCKnEDwkFha51VKEKB6A9wW26/ZNwzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.6.0" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/w3c-web-usb": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz", - "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==", - "license": "MIT", - "optional": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz", - "integrity": "sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/type-utils": "8.41.0", - "@typescript-eslint/utils": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.41.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.41.0.tgz", - "integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.41.0.tgz", - "integrity": "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.41.0", - "@typescript-eslint/types": "^8.41.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", - "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz", - "integrity": "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz", - "integrity": "sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0", - "@typescript-eslint/utils": "8.41.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", - "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", - "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.41.0", - "@typescript-eslint/tsconfig-utils": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", - "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", - "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.41.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@vitest/coverage-v8": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", - "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@bcoe/v8-coverage": "^1.0.2", - "ast-v8-to-istanbul": "^0.3.3", - "debug": "^4.4.1", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.6", - "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.17", - "magicast": "^0.3.5", - "std-env": "^3.9.0", - "test-exclude": "^7.0.1", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "3.2.4", - "vitest": "3.2.4" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } - } - }, - "node_modules/@vitest/eslint-plugin": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz", - "integrity": "sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.24.1" - }, - "peerDependencies": { - "eslint": ">= 8.57.0", - "typescript": ">= 5.0.0", - "vitest": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vitest": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", - "dev": true, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", "license": "MIT", + "optional": true, "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@serialport/parser-delimiter": "11.0.0" + }, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vitest/mocker": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", - "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", - "dev": true, + "node_modules/@serialport/bindings-cpp/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", + "optional": true, "dependencies": { - "@vitest/spy": "3.2.4", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "ms": "2.1.2" }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "engines": { + "node": ">=6.0" }, "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { + "supports-color": { "optional": true } } }, - "node_modules/@vitest/mocker/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, + "node_modules/@serialport/bindings-cpp/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" + "optional": true + }, + "node_modules/@serialport/bindings-cpp/node_modules/node-addon-api": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==", + "license": "MIT", + "optional": true + }, + "node_modules/@serialport/bindings-cpp/node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", - "dev": true, + "node_modules/@serialport/bindings-interface": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", + "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "optional": true, + "engines": { + "node": "^12.22 || ^14.13 || >=16" } }, - "node_modules/@vitest/runner": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", - "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", - "dev": true, + "node_modules/@serialport/parser-byte-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", + "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.4", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" + "optional": true, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vitest/snapshot": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", - "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", - "dev": true, + "node_modules/@serialport/parser-cctalk": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", + "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" + "optional": true, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", - "dev": true, + "node_modules/@serialport/parser-delimiter": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" + "optional": true, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", - "dev": true, + "node_modules/@serialport/parser-inter-byte-timeout": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", + "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" + "optional": true, + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vue/compiler-core": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", - "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", - "dev": true, + "node_modules/@serialport/parser-packet-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", + "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.13", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" + "optional": true, + "engines": { + "node": ">=8.6.0" } }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", - "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", - "dev": true, + "node_modules/@serialport/parser-readline": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", "license": "MIT", + "optional": true, "dependencies": { - "@vue/compiler-core": "3.5.13", - "@vue/shared": "3.5.13" + "@serialport/parser-delimiter": "12.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", - "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", - "dev": true, + "node_modules/@serialport/parser-ready": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", + "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", "license": "MIT", - "peer": true, - "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.13", - "@vue/compiler-dom": "3.5.13", - "@vue/compiler-ssr": "3.5.13", - "@vue/shared": "3.5.13", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.11", - "postcss": "^8.4.48", - "source-map-js": "^1.2.0" + "optional": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", - "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", - "dev": true, + "node_modules/@serialport/parser-regex": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", + "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.13", - "@vue/shared": "3.5.13" + "optional": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/@vue/shared": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", - "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "license": "BSD-2-Clause" - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, + "node_modules/@serialport/parser-slip-encoder": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", + "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, + "optional": true, "engines": { - "node": ">=0.4.0" + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node_modules/@serialport/parser-spacepacket": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", + "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "optional": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, + "node_modules/@serialport/stream": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", + "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", "license": "MIT", + "optional": true, "dependencies": { - "acorn": "^8.11.0" + "@serialport/bindings-interface": "1.2.2", + "debug": "4.3.4" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "node": ">=12.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "url": "https://opencollective.com/serialport/donate" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@serialport/stream/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", + "optional": true, "dependencies": { - "color-convert": "^2.0.1" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/ansis": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", - "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "node_modules/@serialport/stream/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT", + "optional": true + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "@shikijs/types": "3.23.0" } }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "dependencies": { + "@shikijs/types": "3.23.0" } }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=14" + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "dev": true, "license": "MIT" }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "node_modules/@sindresorhus/base62": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/base62/-/base62-1.0.0.tgz", + "integrity": "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/array-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", - "dev": true, + "node_modules/@stoprocent/bluetooth-hci-socket": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@stoprocent/bluetooth-hci-socket/-/bluetooth-hci-socket-2.2.6.tgz", + "integrity": "sha512-elKIsQe78EnxXzxfA/iuqGufD02d6t3S95eNhFaPvTJs7S3IHq2CdIHwTg3BLwae7Jw14mwK0VhWVtNtzrLyoA==", + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "linux", + "android", + "freebsd", + "win32", + "darwin" + ], "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-shim-unscopables": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "async": "^3.2.6", + "debug": "^4.3.7", + "node-addon-api": "^8.3.1", + "node-gyp-build": "^4.8.4", + "patch-package": "^8.0.0", + "serialport": "^12.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "usb": "^2.14.0" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", - "dev": true, + "node_modules/@stoprocent/noble": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@stoprocent/noble/-/noble-2.4.0.tgz", + "integrity": "sha512-tmeHnmo4gH6/2XsAvYupLtxD+M0C9BvbMSnhC+wEfpxWwM82cBTNck0aEfYTDOmtQV5B1Ia47a8oHqrVYN7wEw==", + "hasInstallScript": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "debug": "^4.3.7", + "node-addon-api": "^8.1.0", + "node-gyp-build": "^4.8.1", + "patch-package": "^8.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@stoprocent/bluetooth-hci-socket": "^2.2.6" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "node_modules/@stylistic/eslint-plugin": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "tslib": "^2.4.0" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", - "integrity": "sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==", + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "estree-walker": "^3.0.3", - "js-tokens": "^9.0.1" + "@types/ms": "*" } }, - "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } + "license": "MIT" }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT", - "optional": true + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } + "license": "MIT" }, - "node_modules/async-mutex": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", - "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "license": "ISC", - "engines": { - "node": ">= 4.0.0" + "@types/unist": "*" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "dev": true, "license": "MIT" }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@types/unist": "*" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "undici-types": "~7.19.0" } }, - "node_modules/braces": { + "node_modules/@types/unist": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/w3c-web-usb": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.13.tgz", + "integrity": "sha512-N2nSl3Xsx8mRHZBvMSdNGtzMyeleTvtlEw+ujujgXalPqOjIA6UtrqcB6OzyUjkTbDm3J7P1RNK1lgoO7jxtsw==", "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } + "optional": true }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "node_modules/@typescript-eslint/parser": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz", + "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", + "debug": "^4.4.3" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/builtin-modules": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", - "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", + "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" + "@typescript-eslint/tsconfig-utils": "^8.58.0", + "@typescript-eslint/types": "^8.58.0", + "debug": "^4.4.3" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/@typescript-eslint/rule-tester": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-8.58.0.tgz", + "integrity": "sha512-a/J72Cxeo5ug5sbey7+Dcna6tMBc4Z4eYwBEKM6MVuBqbxnROpLm8yn/j00lPZc75joPZJVR5oiTZxbK95zp+w==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "@typescript-eslint/parser": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/utils": "8.58.0", + "ajv": "^6.12.6", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "4.6.2", + "semver": "^7.7.3" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", + "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", + "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "dev": true, - "license": "MIT", + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.1.tgz", + "integrity": "sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1", + "@typescript-eslint/utils": "8.58.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", + "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@typescript-eslint/tsconfig-utils": "^8.58.1", + "@typescript-eslint/types": "^8.58.1", + "debug": "^4.4.3" }, "engines": { - "node": ">= 8.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", + "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1" }, "engines": { - "node": ">= 6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", + "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/clean-regexp/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", + "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", + "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.58.1", + "@typescript-eslint/tsconfig-utils": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, "engines": { - "node": ">= 12.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.1.tgz", - "integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==", - "dev": true, - "license": "MIT" - }, - "node_modules/core-js-compat": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", - "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", + "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.25.1" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", + "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@typescript-eslint/types": "8.58.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">= 8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", + "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", + "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "@typescript-eslint/project-service": "8.58.0", + "@typescript-eslint/tsconfig-utils": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "node_modules/@typescript-eslint/utils": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz", + "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/inspect-js" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", + "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "@typescript-eslint/types": "8.58.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.4.tgz", + "integrity": "sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w==", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.1.4", + "ast-v8-to-istanbul": "^1.0.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" }, - "engines": { - "node": ">=6.0" + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.1.4", + "vitest": "4.1.4" }, "peerDependenciesMeta": { - "supports-color": { + "@vitest/browser": { "optional": true } } }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "node_modules/@vitest/expect": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz", + "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==", "dev": true, "license": "MIT", "dependencies": { - "character-entities": "^2.0.0" + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.4", + "@vitest/utils": "4.1.4", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://opencollective.com/vitest" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/@vitest/mocker": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz", + "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "@vitest/spy": "4.1.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "^1.0.0" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/@vitest/pretty-format": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz", + "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==", "dev": true, "license": "MIT", "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" + "tinyrainbow": "^3.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/vitest" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/@vitest/runner": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz", + "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "@vitest/utils": "4.1.4", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "node_modules/@vitest/snapshot": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz", + "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==", "dev": true, "license": "MIT", "dependencies": { - "dequal": "^2.0.0" + "@vitest/pretty-format": "4.1.4", + "@vitest/utils": "4.1.4", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://opencollective.com/vitest" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@vitest/spy": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz", + "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/@vitest/utils": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz", + "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==", + "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "@vitest/pretty-format": "4.1.4", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/@vue/compiler-core": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.29.tgz", + "integrity": "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.29.0", + "@vue/shared": "3.5.29", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } }, - "node_modules/electron-to-chromium": { - "version": "1.5.191", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", - "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", + "node_modules/@vue/compiler-dom": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.29.tgz", + "integrity": "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==", "dev": true, - "license": "ISC" + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-core": "3.5.29", + "@vue/shared": "3.5.29" + } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/@vue/compiler-sfc": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.29.tgz", + "integrity": "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.29.0", + "@vue/compiler-core": "3.5.29", + "@vue/compiler-dom": "3.5.29", + "@vue/compiler-ssr": "3.5.29", + "@vue/shared": "3.5.29", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "node_modules/@vue/compiler-ssr": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.29.tgz", + "integrity": "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "once": "^1.4.0" + "@vue/compiler-dom": "3.5.29", + "@vue/shared": "3.5.29" } }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "node_modules/@vue/shared": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.29.tgz", + "integrity": "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "peer": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "license": "BSD-2-Clause" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10.13.0" + "node": ">=0.4.0" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", - "dev": true, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", + "node_modules/ansis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", + "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": ">=14" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=14" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "MIT" + "license": "Python-2.0" }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz", + "integrity": "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" } }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" + "@types/estree": "^1.0.0" } }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT", + "optional": true + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "18 || 20 || >=22" } }, - "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "node_modules/baseline-browser-mapping": { + "version": "2.10.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.16.tgz", + "integrity": "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==", "dev": true, - "hasInstallScript": true, - "license": "MIT", + "license": "Apache-2.0", "bin": { - "esbuild": "bin/esbuild" + "baseline-browser-mapping": "dist/cli.cjs" }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" + "node": ">=6.0.0" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "license": "ISC" }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "balanced-match": "^4.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/eslint": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz", - "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", - "dev": true, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.34.0", - "@eslint/plugin-kit": "^0.3.5", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "fill-range": "^7.1.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } + "node": ">=8" } }, - "node_modules/eslint-compat-utils": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", - "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "semver": "^7.5.4" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, - "engines": { - "node": ">=12" + "bin": { + "browserslist": "cli.js" }, - "peerDependencies": { - "eslint": ">=6.0.0" + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/eslint-config-flat-gitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-2.1.0.tgz", - "integrity": "sha512-cJzNJ7L+psWp5mXM7jBX+fjHtBvvh06RBlcweMhKD8jWqQw0G78hOW5tpVALGHGFPsBV+ot2H+pdDGJy6CV8pA==", + "node_modules/builtin-modules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", + "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", "dev": true, "license": "MIT", - "dependencies": { - "@eslint/compat": "^1.2.5" + "engines": { + "node": ">=18.20" }, "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "eslint": "^9.5.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-flat-config-utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-2.1.1.tgz", - "integrity": "sha512-K8eaPkBemHkfbYsZH7z4lZ/tt6gNSsVh535Wh9W9gQBS2WjvfUbbVr2NZR3L1yiRCLuOEimYfPxCxODczD4Opg==", + "node_modules/cac": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", "dev": true, "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", "dependencies": { - "pathe": "^2.0.3" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-formatting-reporter": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/eslint-formatting-reporter/-/eslint-formatting-reporter-0.0.0.tgz", - "integrity": "sha512-k9RdyTqxqN/wNYVaTk/ds5B5rA8lgoAmvceYN7bcZMBwU7TuXx5ntewJv81eF3pIL/CiJE+pJZm36llG8yhyyw==", - "dev": true, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, - "peerDependencies": { - "eslint": ">=8.40.0" + "engines": { + "node": ">= 0.4" } }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "node_modules/caniuse-lite": { + "version": "1.0.30001786", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001786.tgz", + "integrity": "sha512-4oxTZEvqmLLrERwxO76yfKM7acZo310U+v4kqexI2TL1DkkUEMT8UijrxxcnVdxR3qkVf5awGRX+4Z6aPHVKrA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dev": true, "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">=18" } }, - "node_modules/eslint-json-compat-utils": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", - "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", - "dev": true, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { - "esquery": "^1.6.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": "*", - "jsonc-eslint-parser": "^2.4.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "@eslint/json": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint-merge-processors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-merge-processors/-/eslint-merge-processors-2.0.0.tgz", - "integrity": "sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==", + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "dev": true, "license": "MIT", "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "eslint": "*" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "node": ">=8" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" } }, - "node_modules/eslint-parser-plain": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-parser-plain/-/eslint-parser-plain-0.1.1.tgz", - "integrity": "sha512-KRgd6wuxH4U8kczqPp+Oyk4irThIhHWxgFgLDtpgjUGVIS3wGrJntvZW/p6hHq1T4FOwnOtCNkvAI4Kr+mQ/Hw==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-antfu": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-3.1.1.tgz", - "integrity": "sha512-7Q+NhwLfHJFvopI2HBZbSxWXngTwBLKxW1AGXLr2lEGxcEIK/AsDs8pn8fvIizl5aZjBbVbVK5ujmMpBe4Tvdg==", + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "eslint": "*" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/eslint-plugin-command": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-3.3.1.tgz", - "integrity": "sha512-fBVTXQ2y48TVLT0+4A6PFINp7GcdIailHAXbvPBixE7x+YpYnNQhFZxTdvnb+aWk+COgNebQKen/7m4dmgyWAw==", - "dev": true, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "@es-joy/jsdoccomment": "^0.50.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "color-name": "~1.1.4" }, - "peerDependencies": { - "eslint": "*" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/eslint-plugin-es-x": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", - "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, - "funding": [ - "https://github.com/sponsors/ota-meshi", - "https://opencollective.com/eslint" - ], "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.11.0", - "eslint-compat-utils": "^0.5.1" - }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8" + "node": ">= 12" } }, - "node_modules/eslint-plugin-es-x/node_modules/eslint-compat-utils": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", - "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "node_modules/comment-parser": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.5.tgz", + "integrity": "sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==", "dev": true, "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "node": ">= 12.0.0" } }, - "node_modules/eslint-plugin-format": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-format/-/eslint-plugin-format-1.0.1.tgz", - "integrity": "sha512-Tdns+CDjS+m7QrM85wwRi2yLae88XiWVdIOXjp9mDII0pmTBQlczPCmjpKnjiUIY3yPZNLqb5Ms/A/JXcBF2Dw==", + "node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@dprint/formatter": "^0.3.0", - "@dprint/markdown": "^0.17.8", - "@dprint/toml": "^0.6.4", - "eslint-formatting-reporter": "^0.0.0", - "eslint-parser-plain": "^0.1.1", - "prettier": "^3.4.2", - "synckit": "^0.9.2" + "browserslist": "^4.28.1" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "peerDependencies": { - "eslint": "^8.40.0 || ^9.0.0" + "engines": { + "node": ">= 8" } }, - "node_modules/eslint-plugin-import": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "array.prototype.findlastindex": "^1.2.6", - "array.prototype.flat": "^1.3.3", - "array.prototype.flatmap": "^1.3.3", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "hasown": "^2.0.2", - "is-core-module": "^2.16.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.1", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.9", - "tsconfig-paths": "^3.15.0" + "bin": { + "cssesc": "bin/cssesc" }, "engines": { "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/eslint-plugin-import-lite": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-lite/-/eslint-plugin-import-lite-0.3.0.tgz", - "integrity": "sha512-dkNBAL6jcoCsXZsQ/Tt2yXmMDoNt5NaBh/U7yvccjiK8cai6Ay+MK77bMykmqQA2bTF6lngaLCDij6MTO3KkvA==", - "dev": true, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/types": "^8.34.0" + "ms": "^2.1.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=9.0.0", - "typescript": ">=4.5" + "node": ">=6.0" }, "peerDependenciesMeta": { - "typescript": { + "supports-color": { "optional": true } } }, - "node_modules/eslint-plugin-import-x": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", - "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "^8.35.0", - "comment-parser": "^1.4.1", - "debug": "^4.4.1", - "eslint-import-context": "^0.1.9", - "is-glob": "^4.0.3", - "minimatch": "^9.0.3 || ^10.0.1", - "semver": "^7.7.2", - "stable-hash-x": "^0.2.0", - "unrs-resolver": "^1.9.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "character-entities": "^2.0.0" }, "funding": { - "url": "https://opencollective.com/eslint-plugin-import-x" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "eslint-import-resolver-node": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/utils": { - "optional": true - }, - "eslint-import-resolver-node": { - "optional": true - } + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "MIT" }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "Apache-2.0", + "engines": { + "node": ">=8" } }, - "node_modules/eslint-plugin-jsdoc": { - "version": "52.0.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-52.0.4.tgz", - "integrity": "sha512-be5OzGlLExvcK13Il3noU7/v7WmAQGenTmCaBKf1pwVtPOb6X+PGFVnJad0QhMj4KKf45XjE4hbsBxv25q1fTg==", + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@es-joy/jsdoccomment": "~0.52.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.4.1", - "escape-string-regexp": "^4.0.0", - "espree": "^10.4.0", - "esquery": "^1.6.0", - "parse-imports-exports": "^0.2.4", - "semver": "^7.7.2", - "spdx-expression-parse": "^4.0.0" - }, - "engines": { - "node": ">=20.11.0" + "dequal": "^2.0.0" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { - "version": "0.52.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.52.0.tgz", - "integrity": "sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.8", - "@typescript-eslint/types": "^8.34.1", - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, "engines": { - "node": ">=20.11.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint-plugin-jsonc": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.20.1.tgz", - "integrity": "sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==", - "dev": true, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.5.1", - "eslint-compat-utils": "^0.6.4", - "eslint-json-compat-utils": "^0.2.1", - "espree": "^9.6.1 || ^10.3.0", - "graphemer": "^1.4.0", - "jsonc-eslint-parser": "^2.4.0", - "natural-compare": "^1.4.0", - "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-jsonc/node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "node_modules/electron-to-chromium": { + "version": "1.5.332", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.332.tgz", + "integrity": "sha512-7OOtytmh/rINMLwaFTbcMVvYXO3AUm029X0LcyfYk0B557RlPkdpTpnH9+htMlfu5dKwOmT0+Zs2Aw+lnn6TeQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" + "node": ">=14" } }, - "node_modules/eslint-plugin-jsonc/node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" + "once": "^1.4.0" } }, - "node_modules/eslint-plugin-n": { - "version": "17.21.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.21.3.tgz", - "integrity": "sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==", + "node_modules/enhanced-resolve": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.5.0", - "enhanced-resolve": "^5.17.1", - "eslint-plugin-es-x": "^7.8.0", - "get-tsconfig": "^4.8.1", - "globals": "^15.11.0", - "globrex": "^0.1.2", - "ignore": "^5.3.2", - "semver": "^7.6.3", - "ts-declaration-location": "^1.0.6" + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": ">=8.23.0" + "node": ">=10.13.0" } }, - "node_modules/eslint-plugin-n/node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "peer": true, "engines": { - "node": ">=18" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/eslint-plugin-no-only-tests": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", - "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", - "dev": true, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { - "node": ">=5.0.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-perfectionist": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.15.0.tgz", - "integrity": "sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==", - "dev": true, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "^8.34.1", - "@typescript-eslint/utils": "^8.34.1", - "natural-orderby": "^5.0.0" - }, "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "eslint": ">=8.45.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-pnpm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-pnpm/-/eslint-plugin-pnpm-1.1.0.tgz", - "integrity": "sha512-sL93w0muBtjnogzk/loDsxzMbmXQOLP5Blw3swLDBXZgfb+qQI73bPcUbjVR+ZL+K62vGJdErV+43i3r5DsZPg==", + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/antfu" - }, - { - "type": "individual", - "url": "https://github.com/sponsors/sxzz" - } - ], - "license": "MIT", - "dependencies": { - "find-up-simple": "^1.0.1", - "jsonc-eslint-parser": "^2.4.0", - "pathe": "^2.0.3", - "pnpm-workspace-yaml": "1.1.0", - "tinyglobby": "^0.2.14", - "yaml-eslint-parser": "^1.3.0" - }, - "peerDependencies": { - "eslint": "^9.0.0" - } + "license": "MIT" }, - "node_modules/eslint-plugin-regexp": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.10.0.tgz", - "integrity": "sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==", - "dev": true, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "comment-parser": "^1.4.0", - "jsdoc-type-pratt-parser": "^4.0.0", - "refa": "^0.12.1", - "regexp-ast-analysis": "^0.7.1", - "scslre": "^0.3.0" + "es-errors": "^1.3.0" }, "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "eslint": ">=8.44.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-toml": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.12.0.tgz", - "integrity": "sha512-+/wVObA9DVhwZB1nG83D2OAQRrcQZXy+drqUnFJKymqnmbnbfg/UPmEMCKrJNcEboUGxUjYrJlgy+/Y930mURQ==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "eslint-compat-utils": "^0.6.0", - "lodash": "^4.17.19", - "toml-eslint-parser": "^0.10.0" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "node": ">=6" } }, - "node_modules/eslint-plugin-unicorn": { - "version": "60.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-60.0.0.tgz", - "integrity": "sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "@eslint-community/eslint-utils": "^4.7.0", - "@eslint/plugin-kit": "^0.3.3", - "change-case": "^5.4.4", - "ci-info": "^4.3.0", - "clean-regexp": "^1.0.0", - "core-js-compat": "^3.44.0", - "esquery": "^1.6.0", - "find-up-simple": "^1.0.1", - "globals": "^16.3.0", - "indent-string": "^5.0.0", - "is-builtin-module": "^5.0.0", - "jsesc": "^3.1.0", - "pluralize": "^8.0.0", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.12.0", - "semver": "^7.7.2", - "strip-indent": "^4.0.0" - }, "engines": { - "node": "^20.10.0 || >=21.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=9.29.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-yml": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.18.0.tgz", - "integrity": "sha512-9NtbhHRN2NJa/s3uHchO3qVVZw0vyOIvWlXWGaKCr/6l3Go62wsvJK5byiI6ZoYztDsow4GnS69BZD3GnqH3hA==", + "node_modules/eslint": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", "dev": true, "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "escape-string-regexp": "4.0.0", - "eslint-compat-utils": "^0.6.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", "natural-compare": "^1.4.0", - "yaml-eslint-parser": "^1.2.1" + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/ota-meshi" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "eslint": ">=6.0.0" + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-processor-vue-blocks": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-2.0.0.tgz", - "integrity": "sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==", + "node_modules/eslint-config-flat-gitignore": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-2.3.0.tgz", + "integrity": "sha512-bg4ZLGgoARg1naWfsINUUb/52Ksw/K22K+T16D38Y8v+/sGwwIYrGvH/JBjOin+RQtxxC9tzNNiy4shnGtGyyQ==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint/compat": "^2.0.3" + }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "@vue/compiler-sfc": "^3.3.0", - "eslint": ">=9.0.0" + "eslint": "^9.5.0 || ^10.0.0" } }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "node_modules/eslint-flat-config-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-3.1.0.tgz", + "integrity": "sha512-lM+Nwo2CzpuTS/RASQExlEIwk/BQoKqJWX6VbDlLMb/mveqvt9MMrRXFEkG3bseuK6g8noKZLeX82epkILtv4A==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "@eslint/config-helpers": "^0.5.3", + "pathe": "^2.0.3" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint-formatting-reporter": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/eslint-formatting-reporter/-/eslint-formatting-reporter-0.0.0.tgz", + "integrity": "sha512-k9RdyTqxqN/wNYVaTk/ds5B5rA8lgoAmvceYN7bcZMBwU7TuXx5ntewJv81eF3pIL/CiJE+pJZm36llG8yhyyw==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" + "prettier-linter-helpers": "^1.0.0" }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "node_modules/eslint-json-compat-utils": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.3.tgz", + "integrity": "sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "esquery": "^1.6.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" + "peerDependencies": { + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0 || ^3.0.0" }, - "engines": { - "node": ">=0.10" + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/eslint-merge-processors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-merge-processors/-/eslint-merge-processors-2.0.0.tgz", + "integrity": "sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" + "peerDependencies": { + "eslint": "*" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "node_modules/eslint-parser-plain": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-parser-plain/-/eslint-parser-plain-0.1.1.tgz", + "integrity": "sha512-KRgd6wuxH4U8kczqPp+Oyk4irThIhHWxgFgLDtpgjUGVIS3wGrJntvZW/p6hHq1T4FOwnOtCNkvAI4Kr+mQ/Hw==", "dev": true, "license": "MIT" }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "node_modules/eslint-plugin-antfu": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-3.2.2.tgz", + "integrity": "sha512-Qzixht2Dmd/pMbb5EnKqw2V8TiWHbotPlsORO8a+IzCLFwE0RxK8a9k4DCTFPzBwyxJzH+0m2Mn8IUGeGQkyUw==", "dev": true, "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "funding": { + "url": "https://github.com/sponsors/antfu" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "eslint": "*" } }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "node_modules/eslint-plugin-command": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-3.5.2.tgz", + "integrity": "sha512-PA59QAkQDwvcCMEt5lYLJLI3zDGVKJeC4id/pcRY2XdRYhSGW7iyYT1VC1N3bmpuvu6Qb/9QptiS3GJMjeGTJg==", "dev": true, "license": "MIT", "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "@es-joy/jsdoccomment": "^0.84.0" }, - "engines": { - "node": ">=4.8" + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@typescript-eslint/rule-tester": "*", + "@typescript-eslint/typescript-estree": "*", + "@typescript-eslint/utils": "*", + "eslint": "*" } }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/eslint-plugin-depend": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-depend/-/eslint-plugin-depend-1.5.0.tgz", + "integrity": "sha512-i3UeLYmclf1Icp35+6W7CR4Bp2PIpDgBuf/mpmXK5UeLkZlvYJ21VuQKKHHAIBKRTPivPGX/gZl5JGno1o9Y0A==", "dev": true, "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "dependencies": { + "empathic": "^2.0.0", + "module-replacements": "^2.10.1", + "semver": "^7.6.3" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" }, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" } }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/eslint-plugin-es-x/node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/eslint-plugin-format": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-format/-/eslint-plugin-format-2.0.1.tgz", + "integrity": "sha512-0BA65p5DAiuKtx5MmMJfPk9WaTjoHHbyVW7ZXRhaZoA1fdiMHhay9QRiDL2wr0hJWZxdF7CRThOK/70VUKVg2g==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" + "@dprint/formatter": "^0.5.1", + "@dprint/markdown": "^0.21.1", + "@dprint/toml": "^0.7.0", + "eslint-formatting-reporter": "^0.0.0", + "eslint-parser-plain": "^0.1.1", + "ohash": "^2.0.11", + "oxfmt": "^0.35.0", + "prettier": "^3.8.1", + "synckit": "^0.11.12" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "eslint": "^8.40.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "node_modules/eslint-plugin-import-lite": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-lite/-/eslint-plugin-import-lite-0.6.0.tgz", + "integrity": "sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" } }, - "node_modules/exsolve": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.1.tgz", - "integrity": "sha512-Smf0iQtkQVJLaph8r/qS8C8SWfQkaq9Q/dFcD44MLbJj6DNhlWefVuaS21SjfqOsBbjVlKtbCj6L9ekXK6EZUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/eslint-plugin-jsdoc": { + "version": "62.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.9.0.tgz", + "integrity": "sha512-PY7/X4jrVgoIDncUmITlUqK546Ltmx/Pd4Hdsu4CvSjryQZJI2mEV4vrdMufyTetMiZ5taNSqvK//BTgVUlNkA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" + "@es-joy/jsdoccomment": "~0.86.0", + "@es-joy/resolve.exports": "1.2.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.6", + "debug": "^4.4.3", + "escape-string-regexp": "^4.0.0", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "html-entities": "^2.6.0", + "object-deep-merge": "^2.0.0", + "parse-imports-exports": "^0.2.4", + "semver": "^7.7.4", + "spdx-expression-parse": "^4.0.0", + "to-valid-identifier": "^1.0.0" }, "engines": { - "node": ">=8.6.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.86.0.tgz", + "integrity": "sha512-ukZmRQ81WiTpDWO6D/cTBM7XbrNtutHKvAVnZN/8pldAwLoJArGOvkNyxPTBGsPjsoaQBJxlH+tE2TNA/92Qgw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "@types/estree": "^1.0.8", + "@typescript-eslint/types": "^8.58.0", + "comment-parser": "1.4.6", + "esquery": "^1.7.0", + "jsdoc-type-pratt-parser": "~7.2.0" }, "engines": { - "node": ">= 6" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.6.tgz", + "integrity": "sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "node_modules/eslint-plugin-jsdoc/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "format": "^0.2.0" + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://opencollective.com/eslint" } }, - "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "node_modules/eslint-plugin-jsdoc/node_modules/jsdoc-type-pratt-parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.2.0.tgz", + "integrity": "sha512-dh140MMgjyg3JhJZY/+iEzW+NO5xR2gpbDFKHqotCmexElVntw7GjWjt511+C/Ef02RU5TKYrJo/Xlzk+OLaTw==", "dev": true, "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "engines": { + "node": ">=20.0.0" } }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "node_modules/eslint-plugin-jsonc": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-3.1.2.tgz", + "integrity": "sha512-dopTxdB22iuOkgKyJCupEC5IYBItUT4J/teq1H5ddUObcaYhOURxtJElZczdcYnnKCghNU/vccuyPkliy2Wxsg==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" + "@eslint-community/eslint-utils": "^4.5.1", + "@eslint/core": "^1.0.1", + "@eslint/plugin-kit": "^0.6.0", + "@ota-meshi/ast-token-store": "^0.3.0", + "diff-sequences": "^29.6.3", + "eslint-json-compat-utils": "^0.2.3", + "jsonc-eslint-parser": "^3.1.0", + "natural-compare": "^1.4.0", + "synckit": "^0.11.12" }, "engines": { - "node": ">=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=9.38.0" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/eslint-plugin-n": { + "version": "17.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.24.0.tgz", + "integrity": "sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==", + "dev": true, "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "node_modules/eslint-plugin-n/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-no-only-tests": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", + "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-perfectionist": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.8.0.tgz", + "integrity": "sha512-k8uIptWIxkUclonCFGyDzgYs9NI+Qh0a7cUXS3L7IYZDEsjXuimFBVbxXPQQngWqMiaxJRwbtYB4smMGMqF+cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.58.0", + "natural-orderby": "^5.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "license": "Apache-2.0", + "node_modules/eslint-plugin-pnpm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-pnpm/-/eslint-plugin-pnpm-1.6.0.tgz", + "integrity": "sha512-dxmt9r3zvPaft6IugS4i0k16xag3fTbOvm/road5uV9Y8qUCQT0xzheSh3gMlYAlC6vXRpfArBDsTZ7H7JKCbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT", "dependencies": { - "micromatch": "^4.0.2" + "empathic": "^2.0.0", + "jsonc-eslint-parser": "^3.1.0", + "pathe": "^2.0.3", + "pnpm-workspace-yaml": "1.6.0", + "tinyglobby": "^0.2.15", + "yaml": "^2.8.2", + "yaml-eslint-parser": "^2.0.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "node_modules/eslint-plugin-regexp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.1.0.tgz", + "integrity": "sha512-qGXIC3DIKZHcK1H9A9+Byz9gmndY6TTSRkSMTZpNXdyCw2ObSehRgccJv35n9AdUakEjQp5VFNLas6BMXizCZg==", "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "comment-parser": "^1.4.0", + "jsdoc-type-pratt-parser": "^7.0.0", + "refa": "^0.12.1", + "regexp-ast-analysis": "^0.7.1", + "scslre": "^0.3.0" }, "engines": { - "node": ">=16" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": ">=9.38.0" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "node_modules/eslint-plugin-toml": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-1.3.1.tgz", + "integrity": "sha512-1l00fBP03HIt9IPV7ZxBi7x0y0NMdEZmakL1jBD6N/FoKBvfKxPw5S8XkmzBecOnFBTn5Z8sNJtL5vdf9cpRMQ==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7" + "@eslint/core": "^1.0.1", + "@eslint/plugin-kit": "^0.6.0", + "@ota-meshi/ast-token-store": "^0.3.0", + "debug": "^4.1.1", + "toml-eslint-parser": "^1.0.1" }, "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=9.38.0" } }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "node_modules/eslint-plugin-unicorn": { + "version": "64.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-64.0.0.tgz", + "integrity": "sha512-rNZwalHh8i0UfPlhNwg5BTUO1CMdKNmjqe+TgzOTZnpKoi8VBgsW7u9qCHIdpxEzZ1uwrJrPF0uRb7l//K38gA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "@babel/helper-validator-identifier": "^7.28.5", + "@eslint-community/eslint-utils": "^4.9.1", + "change-case": "^5.4.4", + "ci-info": "^4.4.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.49.0", + "find-up-simple": "^1.0.1", + "globals": "^17.4.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.13.0", + "semver": "^7.7.4", + "strip-indent": "^4.1.1" }, "engines": { - "node": ">=14" + "node": "^20.10.0 || >=21.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=9.38.0" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/eslint-plugin-unused-imports": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", + "integrity": "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==", "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" + "license": "MIT", + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", + "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } } }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "node_modules/eslint-plugin-vue": { + "version": "10.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.8.0.tgz", + "integrity": "sha512-f1J/tcbnrpgC8suPN5AtdJ5MQjuXbSU9pGRSSYAuF3SHoiYCOdEX6O22pLaRyLHXvDcOe+O5ENgc1owQ587agA==", "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^7.1.0", + "semver": "^7.6.3", + "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "vue-eslint-parser": "^10.0.0" + }, + "peerDependenciesMeta": { + "@stylistic/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true + } } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/eslint-plugin-yml": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-3.3.1.tgz", + "integrity": "sha512-isntsZchaTqDMNNkD+CakrgA/pdUoJ45USWBKpuqfAW1MCuw731xX/vrXfoJFZU3tTFr24nCbDYmDfT2+g4QtQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@eslint/core": "^1.0.1", + "@eslint/plugin-kit": "^0.6.0", + "@ota-meshi/ast-token-store": "^0.3.0", + "debug": "^4.3.2", + "diff-sequences": "^29.0.0", + "escape-string-regexp": "5.0.0", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^2.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=9.38.0" } }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "node_modules/eslint-plugin-yml/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/eslint-processor-vue-blocks": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-2.0.0.tgz", + "integrity": "sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==", "dev": true, "license": "MIT", "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.3.0", + "eslint": ">=9.0.0" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/eslint/node_modules/@eslint/plugin-kit": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "pump": "^3.0.0" + "@eslint/core": "^1.2.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=6" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "node_modules/eslint/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">= 4" + } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, - "license": "ISC", + "license": "BSD-3-Clause", "dependencies": { - "is-glob": "^4.0.3" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=0.10" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^1.1.7" + "estraverse": "^5.2.0" }, "engines": { - "node": "*" + "node": ">=4.0" } }, - "node_modules/globals": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", - "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4.0" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, + "peer": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "license": "MIT" - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4.8" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "node_modules/has-proto": { + "node_modules/execa/node_modules/shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.0" + "shebang-regex": "^1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" + "isexe": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "which": "bin/which" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" + "node": ">=12.0.0" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", "dev": true, "license": "MIT" }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } + "license": "MIT" }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true, - "license": "ISC" + "license": "Apache-2.0" }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.6.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=0.8.19" + "node": ">= 6" } }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" + "node_modules/fast-string-truncated-width": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-1.2.1.tgz", + "integrity": "sha512-Q9acT/+Uu3GwGj+5w/zsGuQjh9O1TyywhIwAxHudtWrgF09nHOPrvTLhQevPbttcxjr/SNN7mJmfOw/B1bXgow==", + "dev": true, + "license": "MIT" }, - "node_modules/internal-slot": { + "node_modules/fast-string-width": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-1.1.0.tgz", + "integrity": "sha512-O3fwIVIH5gKB38QNbdg+3760ZmGz0SZMgvwJbA1b2TGXceKE6A2cOlfogh1iw8lr049zPyd7YADHy+B7U4W9bQ==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "fast-string-truncated-width": "^1.2.0" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "node_modules/fast-wrap-ansi": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.1.6.tgz", + "integrity": "sha512-HlUwET7a5gqjURj70D5jl7aC3Zmy4weA1SHUfM0JFI0Ptq987NH2TwbBFLoERhfwk+E+eaq4EK3jXoT+R3yp3w==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.10" + "dependencies": { + "fast-string-width": "^1.1.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "reusify": "^1.0.4" } }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", "dev": true, "license": "MIT", "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "format": "^0.2.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=12.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "binary-extensions": "^2.0.0" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-builtin-module": { + "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", - "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { - "builtin-modules": "^5.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=18.20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "license": "Apache-2.0", "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "micromatch": "^4.0.2" } }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=16" } }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.4.x" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "license": "MIT", - "bin": { - "is-docker": "cli.js" + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6229,66 +4664,89 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" + "pump": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", "dev": true, - "license": "MIT", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", "dependencies": { - "is-extglob": "^2.1.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "node_modules/globals": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -6297,25 +4755,38 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">=8" } }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "es-define-property": "^1.0.0" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6323,91 +4794,109 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 4" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, "engines": { - "node": ">= 0.4" + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.10" } }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "node_modules/is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "builtin-modules": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18.20" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -6416,66 +4905,61 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, "node_modules/is-wsl": { @@ -6527,25 +5011,10 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6556,50 +5025,21 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, "license": "MIT" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/jsdoc-type-pratt-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.1.1.tgz", + "integrity": "sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==", "dev": true, "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": ">=20.0.0" } }, "node_modules/jsesc": { @@ -6630,12 +5070,13 @@ "license": "MIT" }, "node_modules/json-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", - "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", + "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" @@ -6654,74 +5095,41 @@ "dev": true, "license": "MIT" }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/jsonc-eslint-parser": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", - "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-3.1.0.tgz", + "integrity": "sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", + "eslint-visitor-keys": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://github.com/sponsors/ota-meshi" } }, "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -6739,6 +5147,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/katex": { + "version": "0.16.45", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.45.tgz", + "integrity": "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -6772,6 +5197,279 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -6783,15 +5481,15 @@ } }, "node_modules/local-pkg": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", - "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", "dev": true, "license": "MIT", "dependencies": { "mlly": "^1.7.4", - "pkg-types": "^2.0.1", - "quansync": "^0.2.8" + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" }, "engines": { "node": ">=14" @@ -6816,19 +5514,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/longest-streak": { "version": "3.1.0", @@ -6841,20 +5533,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loupe": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", - "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", @@ -6863,25 +5541,25 @@ "license": "MIT" }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" } }, "node_modules/make-dir": { @@ -6900,17 +5578,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, "license": "MIT", "dependencies": { @@ -6925,6 +5596,19 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -6976,9 +5660,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7139,6 +5823,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", @@ -7423,6 +6127,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -7828,39 +6552,17 @@ "node": ">=8.6" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7875,27 +6577,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mlly": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", - "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.14.0", - "pathe": "^2.0.1", - "pkg-types": "^1.3.0", - "ufo": "^1.5.4" + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" } }, "node_modules/mlly/node_modules/confbox": { @@ -7917,6 +6609,13 @@ "pathe": "^2.0.1" } }, + "node_modules/module-replacements": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-2.11.0.tgz", + "integrity": "sha512-j5sNQm3VCpQQ7nTqGeOZtoJtV3uKERgCBm9QRhmGRiXiqkf7iRFOkfxdJRZWLkqYY8PNf4cDQF/WfXUYLENrRA==", + "dev": true, + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -7942,22 +6641,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-postinstall": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.2.tgz", - "integrity": "sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7983,9 +6666,9 @@ "license": "MIT" }, "node_modules/node-addon-api": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", - "integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.6.0.tgz", + "integrity": "sha512-gBVjCaqDlRUk0EwoPNKzIr9KkS9041G/q31IBShPs1Xz6UTA+EXdZADbzqAJQrpDRq71CIMnOP5VMut3SL0z5Q==", "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" @@ -8003,98 +6686,12 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", "dev": true, "license": "MIT" }, - "node_modules/nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -8131,18 +6728,12 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "node_modules/object-deep-merge": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-2.0.0.tgz", + "integrity": "sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/object-keys": { "version": "1.1.1", @@ -8153,84 +6744,29 @@ "node": ">= 0.4" } }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -8270,31 +6806,44 @@ "node": ">= 0.8.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "node_modules/oxfmt": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.35.0.tgz", + "integrity": "sha512-QYeXWkP+aLt7utt5SLivNIk09glWx9QE235ODjgcEZ3sd1VMaUBSpLymh6ZRCA76gD2rMP4bXanUz/fx+nLM9Q==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" + "tinypool": "2.1.0" + }, + "bin": { + "oxfmt": "bin/oxfmt" }, "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || >=22.12.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxfmt/binding-android-arm-eabi": "0.35.0", + "@oxfmt/binding-android-arm64": "0.35.0", + "@oxfmt/binding-darwin-arm64": "0.35.0", + "@oxfmt/binding-darwin-x64": "0.35.0", + "@oxfmt/binding-freebsd-x64": "0.35.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.35.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.35.0", + "@oxfmt/binding-linux-arm64-gnu": "0.35.0", + "@oxfmt/binding-linux-arm64-musl": "0.35.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.35.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.35.0", + "@oxfmt/binding-linux-riscv64-musl": "0.35.0", + "@oxfmt/binding-linux-s390x-gnu": "0.35.0", + "@oxfmt/binding-linux-x64-gnu": "0.35.0", + "@oxfmt/binding-linux-x64-musl": "0.35.0", + "@oxfmt/binding-openharmony-arm64": "0.35.0", + "@oxfmt/binding-win32-arm64-msvc": "0.35.0", + "@oxfmt/binding-win32-ia32-msvc": "0.35.0", + "@oxfmt/binding-win32-x64-msvc": "0.35.0" } }, "node_modules/p-finally": { @@ -8339,33 +6888,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/package-manager-detector": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", - "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", "dev": true, "license": "MIT" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse-gitignore": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-2.0.0.tgz", @@ -8394,9 +6923,9 @@ "license": "MIT" }, "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", "license": "MIT", "dependencies": { "@yarnpkg/lockfile": "^1.1.0", @@ -8404,15 +6933,14 @@ "ci-info": "^3.7.0", "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", + "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", - "rimraf": "^2.6.3", "semver": "^7.5.3", "slash": "^2.0.0", - "tmp": "^0.0.33", + "tmp": "^0.2.4", "yaml": "^2.2.2" }, "bin": { @@ -8438,15 +6966,6 @@ "node": ">=8" } }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8457,15 +6976,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -8482,23 +6992,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -8506,16 +6999,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8524,27 +7007,26 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", "dev": true, "license": "MIT", "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", + "confbox": "^0.2.2", + "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, @@ -8559,9 +7041,9 @@ } }, "node_modules/pnpm-workspace-yaml": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pnpm-workspace-yaml/-/pnpm-workspace-yaml-1.1.0.tgz", - "integrity": "sha512-OWUzBxtitpyUV0fBYYwLAfWxn3mSzVbVB7cwgNaHvTTU9P0V2QHjyaY5i7f1hEiT9VeKsNH1Skfhe2E3lx/zhA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pnpm-workspace-yaml/-/pnpm-workspace-yaml-1.6.0.tgz", + "integrity": "sha512-uUy4dK3E11sp7nK+hnT7uAWfkBMe00KaUw8OG3NuNlYQoTk4sc9pcdIy1+XIP85v9Tvr02mK3JPaNNrP0QyRaw==", "dev": true, "funding": [ { @@ -8575,23 +7057,13 @@ ], "license": "MIT", "dependencies": { - "yaml": "^2.8.0" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" + "yaml": "^2.8.2" } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -8618,9 +7090,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", "dependencies": { @@ -8642,9 +7114,9 @@ } }, "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -8658,9 +7130,9 @@ } }, "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", "dev": true, "license": "MIT", "dependencies": { @@ -8670,17 +7142,10 @@ "node": ">=6.0.0" } }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "dev": true, "license": "MIT", "dependencies": { @@ -8709,9 +7174,9 @@ } }, "node_modules/quansync": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.8.tgz", - "integrity": "sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", "dev": true, "funding": [ { @@ -8746,32 +7211,6 @@ ], "license": "MIT" }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -8791,33 +7230,10 @@ "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.8.0" - }, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" + "@eslint-community/regexpp": "^4.8.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/regexp-ast-analysis": { @@ -8844,61 +7260,40 @@ "regexp-tree": "bin/regexp-tree" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~3.0.2" + "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "node_modules/reserved-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz", + "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==", "dev": true, "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -8912,16 +7307,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -8943,57 +7328,38 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/rollup": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", - "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", + "node_modules/rolldown": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", + "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@oxc-project/types": "=0.124.0", + "@rolldown/pluginutils": "1.0.0-rc.15" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.45.1", - "@rollup/rollup-android-arm64": "4.45.1", - "@rollup/rollup-darwin-arm64": "4.45.1", - "@rollup/rollup-darwin-x64": "4.45.1", - "@rollup/rollup-freebsd-arm64": "4.45.1", - "@rollup/rollup-freebsd-x64": "4.45.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", - "@rollup/rollup-linux-arm-musleabihf": "4.45.1", - "@rollup/rollup-linux-arm64-gnu": "4.45.1", - "@rollup/rollup-linux-arm64-musl": "4.45.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-musl": "4.45.1", - "@rollup/rollup-linux-s390x-gnu": "4.45.1", - "@rollup/rollup-linux-x64-gnu": "4.45.1", - "@rollup/rollup-linux-x64-musl": "4.45.1", - "@rollup/rollup-win32-arm64-msvc": "4.45.1", - "@rollup/rollup-win32-ia32-msvc": "4.45.1", - "@rollup/rollup-win32-x64-msvc": "4.45.1", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.0.0-rc.15", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", + "@rolldown/binding-darwin-x64": "1.0.0-rc.15", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" } }, "node_modules/run-parallel": { @@ -9020,61 +7386,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/scslre": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", @@ -9091,9 +7402,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -9173,37 +7484,6 @@ "node": ">= 0.4" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -9261,82 +7541,6 @@ "node": ">=18" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -9351,235 +7555,70 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "dev": true, - "license": "MIT" - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "CC-BY-3.0" }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "CC0-1.0" }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "node_modules/std-env": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", + "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } + "license": "MIT" }, "node_modules/strip-eof": { "version": "1.0.0", @@ -9592,14 +7631,11 @@ } }, "node_modules/strip-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", "dev": true, "license": "MIT", - "dependencies": { - "min-indent": "^1.0.1" - }, "engines": { "node": ">=12" }, @@ -9607,32 +7643,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9659,66 +7669,33 @@ } }, "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" + "@pkgr/core": "^0.2.9" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/unts" + "url": "https://opencollective.com/synckit" } }, "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" - } - }, - "node_modules/test-exclude": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", - "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^9.0.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/tinybench": { @@ -9729,21 +7706,24 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -9753,29 +7733,19 @@ } }, "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", + "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.0.0 || >=22.0.0" } }, "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", - "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -9783,15 +7753,12 @@ } }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -9806,257 +7773,121 @@ "node": ">=8.0" } }, - "node_modules/toml-eslint-parser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.10.0.tgz", - "integrity": "sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - } - }, - "node_modules/toml-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/ts-declaration-location": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", - "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", - "dev": true, - "funding": [ - { - "type": "ko-fi", - "url": "https://ko-fi.com/rebeccastevens" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" - } - ], - "license": "BSD-3-Clause", - "dependencies": { - "picomatch": "^4.0.2" - }, - "peerDependencies": { - "typescript": ">=4.0.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/to-valid-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-valid-identifier/-/to-valid-identifier-1.0.0.tgz", + "integrity": "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" + "@sindresorhus/base62": "^1.0.0", + "reserved-identifiers": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { + "node_modules/toml-eslint-parser": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-1.0.3.tgz", + "integrity": "sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" } }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "node_modules/toml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, "engines": { - "node": ">= 0.4" + "node": ">=18.12" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "typescript": ">=4.8.4" } }, - "node_modules/typed-array-length": { + "node_modules/ts-declaration-location": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8.0" } }, "node_modules/typedoc": { - "version": "0.28.11", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.11.tgz", - "integrity": "sha512-1FqgrrUYGNuE3kImAiEDgAVVVacxdO4ZVTKbiOVDGkoeSB4sNwQaDpa8mta+Lw5TEzBFmGXzsg0I1NLRIoaSFw==", + "version": "0.28.18", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.18.tgz", + "integrity": "sha512-NTWTUOFRQ9+SGKKTuWKUioUkjxNwtS3JDRPVKZAXGHZy2wCA8bdv2iJiyeePn0xkmK+TCCqZFT0X7+2+FLjngA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@gerrit0/mini-shiki": "^3.9.0", + "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", - "markdown-it": "^14.1.0", - "minimatch": "^9.0.5", - "yaml": "^2.8.0" + "markdown-it": "^14.1.1", + "minimatch": "^10.2.4", + "yaml": "^2.8.2" }, "bin": { "typedoc": "bin/typedoc" @@ -10066,16 +7897,15 @@ "pnpm": ">= 10" }, "peerDependencies": { - "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" } }, "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10092,58 +7922,32 @@ "license": "MIT" }, "node_modules/ufo": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", - "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", "dev": true, "license": "MIT" }, "node_modules/undici": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.15.0.tgz", - "integrity": "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.0.2.tgz", + "integrity": "sha512-B9MeU5wuFhkFAuNeA19K2GDFcQXZxq33fL0nRy2Aq30wdufZbyyvxW3/ChaeipXVfy/wUweZyzovQGk39+9k2w==", "license": "MIT", "engines": { - "node": ">=20.18.1" + "node": ">=22.19.0" } }, "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "dev": true, "license": "MIT" }, "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "dev": true, "license": "MIT", "dependencies": { @@ -10154,6 +7958,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -10169,9 +7988,9 @@ } }, "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "dev": true, "license": "MIT", "dependencies": { @@ -10185,9 +8004,9 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10208,46 +8027,10 @@ "node": ">= 10.0.0" } }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -10286,9 +8069,9 @@ } }, "node_modules/usb": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/usb/-/usb-2.14.0.tgz", - "integrity": "sha512-I3lzVOH21BsO6qPYvx1C7Ji08lbuM0qmsEtNGAphqlhNME5cz/vExY+jIXZl+HQIRybI/sTxdyLab5tALsL69w==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/usb/-/usb-2.17.0.tgz", + "integrity": "sha512-UuFgrlglgDn5ll6d5l7kl3nDb2Yx43qLUGcDq+7UNLZLtbNug0HZBb2Xodhgx2JZB1LqvU+dOGqLEeYUeZqsHg==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -10308,27 +8091,18 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, "node_modules/vite": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", - "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", + "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.6", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.40.0", - "tinyglobby": "^0.2.14" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.15", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" @@ -10344,9 +8118,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -10359,13 +8134,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -10391,90 +8169,80 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vitest": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", - "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", - "@vitest/pretty-format": "^3.2.4", - "@vitest/runner": "3.2.4", - "@vitest/snapshot": "3.2.4", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz", + "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.4", + "@vitest/mocker": "4.1.4", + "@vitest/pretty-format": "4.1.4", + "@vitest/runner": "4.1.4", + "@vitest/snapshot": "4.1.4", + "@vitest/spy": "4.1.4", + "@vitest/utils": "4.1.4", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.4", - "@vitest/ui": "3.2.4", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.4", + "@vitest/browser-preview": "4.1.4", + "@vitest/browser-webdriverio": "4.1.4", + "@vitest/coverage-istanbul": "4.1.4", + "@vitest/coverage-v8": "4.1.4", + "@vitest/ui": "4.1.4", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { @@ -10485,28 +8253,23 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, - "node_modules/vitest/node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/vue-eslint-parser": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", - "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.4.0.tgz", + "integrity": "sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.2.0 || ^9.0.0", + "eslint-visitor-keys": "^4.2.0 || ^5.0.0", + "espree": "^10.3.0 || ^11.0.0", "esquery": "^1.6.0", "semver": "^7.6.3" }, @@ -10517,7 +8280,7 @@ "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" } }, "node_modules/which": { @@ -10535,95 +8298,6 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -10651,29 +8325,11 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/xml-name-validator": { @@ -10687,57 +8343,50 @@ } }, "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yaml-eslint-parser": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.3.0.tgz", - "integrity": "sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-2.0.0.tgz", + "integrity": "sha512-h0uDm97wvT2bokfwwTmY6kJ1hp6YDFL0nRHwNKz8s/VD1FH/vvZjAKoMUE+un0eaYBSG7/c6h+lJTP+31tjgTw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.0.0", + "eslint-visitor-keys": "^5.0.0", "yaml": "^2.0.0" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://github.com/sponsors/ota-meshi" } }, "node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -10763,4 +8412,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index b360d0ae..3cf58c74 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "node-switchbot", "type": "module", - "version": "3.6.6", - "description": "The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE).", + "version": "4.0.0", + "description": "The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE) with automatic OpenAPI fallback.", "author": "OpenWonderLabs (https://github.com/OpenWonderLabs)", "license": "MIT", "homepage": "https://github.com/OpenWonderLabs/node-switchbot", @@ -31,52 +31,60 @@ ], "main": "dist/index.js", "types": "dist/index.d.ts", + "files": [ + "BLE.md", + "CHANGELOG.md", + "LICENSE", + "OpenAPI.md", + "README.md", + "dist/" + ], "engines": { "node": "^20 || ^22 || ^24" }, "scripts": { "check": "npm install && npm outdated", - "lint": "eslint src/**/*.ts", - "lint:fix": "eslint src/**/*.ts --fix", + "type-check": "tsc --noEmit", + "lint": "eslint src/**/*.ts test/**/*.ts && npm run type-check", + "lint:fix": "eslint src/**/*.ts test/**/*.ts --fix && npm run type-check", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint test/**/*.ts", "watch": "npm run build && npm link && nodemon", - "build": "npm run clean && tsc", + "build": "npm run clean && tsc -p tsconfig.build.json", "prepublishOnly": "npm run lint && npm run build && npm run docs && npm run lint-docs", "postpublish": "npm run clean && npm ci", "clean": "shx rm -rf ./dist", "test": "vitest run", "test:watch": "vitest watch", "test-coverage": "npm run test -- --coverage", + "ble:scan": "node tmp-switchbot-scan.mjs", "docs": "typedoc", "lint-docs": "typedoc --emit none --treatWarningsAsErrors" }, "readmeFilename": "README.md", "dependencies": { - "@stoprocent/noble": "^2.3.14", - "async-mutex": "^0.5.0", - "undici": "^7.15.0" + "@stoprocent/noble": "^2.4.0", + "undici": "^8.0.2" }, "optionalDependencies": { - "@stoprocent/bluetooth-hci-socket": "^2.2.3" + "@stoprocent/bluetooth-hci-socket": "^2.2.5" }, "devDependencies": { - "@antfu/eslint-config": "^5.2.1", - "@types/aes-js": "^3.1.4", - "@types/debug": "^4.1.12", - "@types/fs-extra": "^11.0.4", - "@types/mdast": "^4.0.4", - "@types/node": "^24.3.0", - "@types/semver": "^7.7.0", - "@types/source-map-support": "^0.5.10", - "@vitest/coverage-v8": "^3.2.4", - "eslint": "^9.34.0", - "eslint-plugin-format": "^1.0.1", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-import-x": "^4.16.1", - "nodemon": "^3.1.10", + "@antfu/eslint-config": "^8.1.1", + "@types/node": "^25.6.0", + "@vitest/coverage-v8": "^4.1.4", + "eslint": "^10.2.0", + "eslint-plugin-format": "^2.0.1", + "eslint-plugin-perfectionist": "^5.8.0", "shx": "^0.4.0", - "ts-node": "^10.9.2", - "typedoc": "^0.28.11", - "typescript": "^5.9.2", - "vitest": "^3.2.4" + "typedoc": "^0.28.18", + "typescript": "^6.0.2", + "vitest": "^4.1.4" + }, + "overrides": { + "brace-expansion": "^5.0.5", + "flatted": "^3.4.0", + "picomatch": "^2.3.2", + "yaml": "^2.8.3" } -} \ No newline at end of file +} diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 00000000..b1852d72 --- /dev/null +++ b/src/api.ts @@ -0,0 +1,354 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * api.ts: SwitchBot v4.0.0 - OpenAPI Client + */ + +import type { APICommandRequest, APICommandResponse, APIDevice, APIDeviceStatus, APIResponse, DeviceListResponse, SceneListResponse, WebhookConfig, WebhookQueryResponse, WebhookSetupResponse } from './types/api.js' + +import { request } from 'undici' + +import { urls } from './settings.js' +import { createSignature, generateNonce, generateTimestamp, Logger } from './utils/index.js' + +/** + * OpenAPI Client for SwitchBot API v1.1 + */ +export class OpenAPIClient { + private logger: Logger + + constructor( + private token: string, + private secret: string, + private baseURL: string = urls.base, + logLevel?: number, + ) { + this.logger = new Logger('OpenAPIClient', logLevel) + + if (!token || !secret) { + throw new Error('OpenAPI token and secret are required') + } + } + + /** + * Generate authentication headers for API requests + */ + private async generateHeaders(): Promise> { + const timestamp = generateTimestamp() + const nonce = generateNonce() + const sign = await createSignature(this.token, this.secret, timestamp, nonce) + + return { + 'Authorization': this.token, + 'Content-Type': 'application/json', + 't': timestamp, + 'sign': sign, + 'nonce': nonce, + } + } + + /** + * Make an API request + */ + private async makeRequest( + method: 'GET' | 'POST' | 'PUT' | 'DELETE', + path: string, + body?: any, + ): Promise> { + const headers = await this.generateHeaders() + const url = `${this.baseURL}${path}` + + this.logger.debug(`${method} ${url}`, body ? { body } : {}) + + try { + const response = await request(url, { + method, + headers, + body: body ? JSON.stringify(body) : undefined, + }) + + const data = await response.body.json() as APIResponse + + if (data.statusCode !== 100 && data.statusCode !== 200) { + this.logger.error('API request failed', data) + throw new Error(`API Error ${data.statusCode}: ${data.message}`) + } + + this.logger.debug('API response', data) + return data + } catch (error) { + this.logger.error('API request error', error) + throw error + } + } + + /** + * Get all devices + */ + async getDevices(): Promise { + const response = await this.makeRequest('GET', '/v1.1/devices') + return response.body + } + + /** + * Get device status + */ + async getStatus(deviceId: string): Promise { + const response = await this.makeRequest('GET', `/v1.1/devices/${deviceId}/status`) + return response.body + } + + /** + * Send command to device + */ + async sendCommand( + deviceId: string, + command: string, + parameter?: any, + ): Promise { + const body: APICommandRequest = { + command, + parameter: parameter !== undefined ? parameter : 'default', + } + + const response = await this.makeRequest('POST', `/v1.1/devices/${deviceId}/commands`, body) + + return { + statusCode: response.statusCode, + message: response.message, + body: response.body, + } + } + + /** + * Get all scenes + */ + async getScenes(): Promise { + const response = await this.makeRequest('GET', '/v1.1/scenes') + return response.body + } + + /** + * Execute a scene + */ + async executeScene(sceneId: string): Promise { + await this.makeRequest('POST', `/v1.1/scenes/${sceneId}/execute`) + } + + /** + * Setup webhook + */ + async setupWebhook(config: WebhookConfig): Promise { + const response = await this.makeRequest('POST', '/v1.1/webhook/setupWebhook', config) + + return { + statusCode: response.statusCode, + message: response.message, + body: response.body, + } + } + + /** + * Query webhook configuration + */ + async queryWebhook(urls?: string[]): Promise { + const body = urls ? { urls } : {} + const response = await this.makeRequest('POST', '/v1.1/webhook/queryWebhook', body) + + return { + statusCode: response.statusCode, + message: response.message, + body: response.body, + } + } + + /** + * Update webhook + */ + async updateWebhook(config: WebhookConfig): Promise { + await this.makeRequest('POST', '/v1.1/webhook/updateWebhook', config) + } + + /** + * Delete webhook + */ + async deleteWebhook(url: string): Promise { + await this.makeRequest('POST', '/v1.1/webhook/deleteWebhook', { url }) + } + + /** + * Get specific device information + */ + async getDevice(deviceId: string): Promise { + const devices = await this.getDevices() + return devices.deviceList.find(d => d.deviceId === deviceId) + } + + /** + * Get devices by type + */ + async getDevicesByType(deviceType: string): Promise { + const devices = await this.getDevices() + return devices.deviceList.filter(d => d.deviceType === deviceType) + } + + /** + * Check if device has cloud service enabled + */ + async isCloudServiceEnabled(deviceId: string): Promise { + const device = await this.getDevice(deviceId) + return device?.enableCloudService ?? false + } + + /** + * Bot-specific commands + */ + async botPress(deviceId: string): Promise { + return this.sendCommand(deviceId, 'press') + } + + async botTurnOn(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOn') + } + + async botTurnOff(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOff') + } + + /** + * Curtain-specific commands + */ + async curtainOpen(deviceId: string, speed = 255): Promise { + const clampedSpeed = Math.min(255, Math.max(1, speed)) + return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},0`) + } + + async curtainClose(deviceId: string, speed = 255): Promise { + const clampedSpeed = Math.min(255, Math.max(1, speed)) + return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},100`) + } + + async curtainPause(deviceId: string): Promise { + return this.sendCommand(deviceId, 'pause') + } + + async curtainSetPosition(deviceId: string, position: number, speed = 255): Promise { + const clampedSpeed = Math.min(255, Math.max(1, speed)) + return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},${position}`) + } + + /** + * Lock-specific commands + */ + async lockLock(deviceId: string): Promise { + return this.sendCommand(deviceId, 'lock') + } + + async lockUnlock(deviceId: string): Promise { + return this.sendCommand(deviceId, 'unlock') + } + + /** + * Plug-specific commands + */ + async plugTurnOn(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOn') + } + + async plugTurnOff(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOff') + } + + async plugToggle(deviceId: string): Promise { + return this.sendCommand(deviceId, 'toggle') + } + + /** + * Bulb/Light-specific commands + */ + async lightTurnOn(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOn') + } + + async lightTurnOff(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOff') + } + + async lightSetBrightness(deviceId: string, brightness: number): Promise { + return this.sendCommand(deviceId, 'setBrightness', brightness) + } + + async lightSetColor(deviceId: string, red: number, green: number, blue: number): Promise { + return this.sendCommand(deviceId, 'setColor', `${red}:${green}:${blue}`) + } + + async lightSetColorTemperature(deviceId: string, temperature: number): Promise { + return this.sendCommand(deviceId, 'setColorTemperature', temperature) + } + + /** + * Humidifier-specific commands + */ + async humidifierTurnOn(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOn') + } + + async humidifierTurnOff(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOff') + } + + async humidifierSetMode(deviceId: string, mode: 'auto' | 'manual'): Promise { + return this.sendCommand(deviceId, 'setMode', mode === 'auto' ? 'auto' : '101') + } + + /** + * Air Purifier-specific commands + */ + async airPurifierTurnOn(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOn') + } + + async airPurifierTurnOff(deviceId: string): Promise { + return this.sendCommand(deviceId, 'turnOff') + } + + async airPurifierSetMode(deviceId: string, mode: 'auto' | 'manual' | 'sleep'): Promise { + return this.sendCommand(deviceId, 'setMode', mode) + } + + async airPurifierSetFanSpeed(deviceId: string, speed: number): Promise { + return this.sendCommand(deviceId, 'setFanSpeed', speed) + } + + /** + * Blind Tilt-specific commands + */ + async blindTiltOpen(deviceId: string): Promise { + return this.sendCommand(deviceId, 'setPosition', '0,ff,0') + } + + async blindTiltClose(deviceId: string): Promise { + return this.sendCommand(deviceId, 'setPosition', '0,ff,100') + } + + async blindTiltSetPosition(deviceId: string, position: number): Promise { + return this.sendCommand(deviceId, 'setPosition', `0,ff,${position}`) + } + + /** + * Get client configuration + */ + getConfig(): { token: string, baseURL: string } { + return { + token: this.token, + baseURL: this.baseURL, + } + } + + /** + * Update base URL + */ + setBaseURL(newBaseURL: string): void { + this.baseURL = newBaseURL + this.logger.info(`Base URL updated to ${newBaseURL}`) + } +} diff --git a/src/ble.ts b/src/ble.ts new file mode 100644 index 00000000..d620cc2e --- /dev/null +++ b/src/ble.ts @@ -0,0 +1,1115 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * ble.ts: SwitchBot v4.0.0 - BLE Discovery and Communication + */ + +import type { BLEAdvertisement, BLEScanOptions, BLEServiceData } from './types/ble.js' + +import { Buffer } from 'node:buffer' +import { createCipheriv } from 'node:crypto' + +import { EventEmitter } from 'node:events' + +import { BLENotAvailableError, CommandFailedError, DeviceNotFoundError } from './errors.js' +import { BLE_COMMAND_TIMEOUT, BLE_CONNECT_TIMEOUT, BLE_NOTIFY_CHARACTERISTIC_UUID, BLE_SCAN_TIMEOUT, BLE_SERVICE_UUID, BLE_WRITE_CHARACTERISTIC_UUID, DEVICE_MODEL_MAP } from './settings.js' +import { extractMacFromManufacturerData, Logger, macToDeviceId, mergeAdvertisement, normalizeMAC, withTimeout } from './utils/index.js' +// Move RegExp to module scope to avoid re-compilation +const CHARACTERISTIC_REGEX = /characteristic/i +const UUID_DASH_REGEX = /-/g + +/** + * BLE Scanner for discovering SwitchBot devices + */ +export class BLEScanner extends EventEmitter { + private noble: any + private logger: Logger + private scanning = false + private discoveredDevices: Map = new Map() + private discoveredModelCache: Map = new Map() + private nobleStateHandler?: (state: string) => void + private nobleDiscoverHandler?: (peripheral: any) => void + private nobleScanStartHandler?: () => void + private nobleScanStopHandler?: () => void + private noblePromise: Promise | null = null + + constructor(options: { noble?: any, logLevel?: number } = {}) { + super() + this.logger = new Logger('BLEScanner', options.logLevel) + this.noble = options.noble + + if (!this.noble) { + this.initializeNoble().catch((error) => { + this.logger.error('Failed to initialize Noble', error) + }) + } else { + this.setupNobleHandlers() + } + } + + /** + * Initialize Noble lazily + */ + private async initializeNoble(): Promise { + if (this.noble) { + return + } + + if (this.noblePromise) { + // Wait for existing initialization to complete + this.noble = await this.noblePromise + return + } + + this.noblePromise = (async () => { + try { + const module = await import('@stoprocent/noble') + return module.default + } catch (error) { + throw new BLENotAvailableError('BLE not supported on this platform or @stoprocent/noble not installed') + } + })() + + try { + this.noble = await this.noblePromise + this.setupNobleHandlers() + } catch (error) { + throw new BLENotAvailableError('BLE not supported on this platform or @stoprocent/noble not installed') + } + } + + /** + * Ensure Noble is loaded before operations + */ + private async ensureNoble(): Promise { + if (!this.noble) { + await this.initializeNoble() + } + + if (!this.noble) { + throw new BLENotAvailableError('BLE not available - noble failed to initialize') + } + } + + /** + * Setup Noble event handlers + */ + private setupNobleHandlers(): void { + // Prevent duplicate listeners if handlers are re-initialized + this.removeNobleHandlers() + + // Store handlers as properties for later cleanup + this.nobleStateHandler = (state: string) => { + this.logger.debug('Noble state changed:', state) + this.emit('state-change', state) + + if (state === 'poweredOn') { + this.emit('ready') + } + } + + this.nobleDiscoverHandler = (peripheral: any) => { + this.handleDiscovery(peripheral) + } + + this.nobleScanStartHandler = () => { + this.scanning = true + this.logger.info('BLE scan started') + this.emit('scan-start') + } + + this.nobleScanStopHandler = () => { + this.scanning = false + this.logger.info('BLE scan stopped') + this.emit('scan-stop') + } + + this.noble.on('stateChange', this.nobleStateHandler) + this.noble.on('discover', this.nobleDiscoverHandler) + this.noble.on('scanStart', this.nobleScanStartHandler) + this.noble.on('scanStop', this.nobleScanStopHandler) + } + + /** + * Remove Noble event handlers + */ + private removeNobleHandlers(): void { + if (this.nobleStateHandler) { + this.noble.off('stateChange', this.nobleStateHandler) + } + if (this.nobleDiscoverHandler) { + this.noble.off('discover', this.nobleDiscoverHandler) + } + if (this.nobleScanStartHandler) { + this.noble.off('scanStart', this.nobleScanStartHandler) + } + if (this.nobleScanStopHandler) { + this.noble.off('scanStop', this.nobleScanStopHandler) + } + + this.nobleStateHandler = undefined + this.nobleDiscoverHandler = undefined + this.nobleScanStartHandler = undefined + this.nobleScanStopHandler = undefined + } + + /** + * Handle device discovery + */ + private handleDiscovery(peripheral: any): void { + try { + // Validate peripheral has required properties + if (!peripheral || typeof peripheral !== 'object') { + return + } + + const { advertisement, address, rssi, connectable } = peripheral + + // Skip non-connectable devices + if (connectable === false) { + return + } + + // Skip devices with invalid RSSI (typical range: -120 to 0 dBm) + if (typeof rssi !== 'number' || rssi < -120 || rssi > 0) { + return + } + + // Validate advertisement object exists and has service data + if (!advertisement || typeof advertisement !== 'object') { + return + } + + if (!Array.isArray(advertisement.serviceData) || advertisement.serviceData.length === 0) { + return + } + + for (const serviceDataItem of advertisement.serviceData) { + // Validate service data item has required properties + if (!serviceDataItem || typeof serviceDataItem !== 'object') { + continue + } + + // SwitchBot service UUID (current: fd3d, legacy: 000d) + const uuid = typeof serviceDataItem.uuid === 'string' ? serviceDataItem.uuid.toLowerCase() : '' + const isSwitchBotUUID = uuid === 'fd3d' + || uuid === '0000fd3d-0000-1000-8000-00805f9b34fb' + || uuid === '000d' + || uuid === '0000000d-0000-1000-8000-00805f9b34fb' + + if (!isSwitchBotUUID) { + continue + } + + const serviceData = this.parseServiceData(serviceDataItem.data) + + if (!serviceData) { + continue + } + + let normalizedAddress = typeof address === 'string' && address.length > 0 ? normalizeMAC(address) : undefined + + // Fallback to manufacturer data MAC if service data address is empty + if (!normalizedAddress) { + const manufacturerMac = extractMacFromManufacturerData(peripheral.advertisement?.manufacturerData) + if (manufacturerMac) { + normalizedAddress = manufacturerMac + } + } + + const fallbackId = typeof peripheral.id === 'string' && peripheral.id.length > 0 + ? peripheral.id + : (normalizedAddress ? macToDeviceId(normalizedAddress) : undefined) + + if (!fallbackId) { + this.logger.debug('Skipping BLE discovery with no address and no peripheral id') + continue + } + + // Determine if advertisement is encrypted (simple heuristic: check for known encrypted models or data length) + // This can be refined as needed + const isEncrypted = !!(serviceData && typeof serviceData.model === 'string' && serviceData.model.startsWith('!')) + + // Try to get a friendly model name (from serviceData or fallback to model code) + const modelFriendlyName = serviceData?.modelName || serviceData?.model || undefined + + // Attempt to get the raw advertisement data (from serviceDataItem.data or peripheral.advertisement) + const rawAdvData = serviceDataItem?.data || peripheral.advertisement?.serviceData?.[0]?.data || undefined + + const advertisement: BLEAdvertisement = { + id: fallbackId, + address: normalizedAddress, + isAddressable: normalizedAddress !== undefined, + rssi, + serviceData, + rawAdvData, + isEncrypted, + modelFriendlyName, + } + + const discoveryKey = normalizedAddress ?? `id:${fallbackId}` + // Merge with previous advertisement if present + const prev = this.discoveredDevices.get(discoveryKey) + if (prev) { + const merged = mergeAdvertisement(prev, advertisement) + this.discoveredDevices.set(discoveryKey, merged) + } else { + this.discoveredDevices.set(discoveryKey, advertisement) + } + this.discoveredModelCache.set(discoveryKey, serviceData.model) + this.emit('discover', advertisement) + this.logger.debug(`Discovered ${serviceData.modelName} at ${normalizedAddress ?? fallbackId}`) + } + } catch (error) { + this.logger.error('Error handling discovery', error) + } + } + + /** + * Parse service data from BLE advertisement + */ + private parseServiceData(data: Buffer): BLEServiceData | null { + if (!data || data.length < 1) { + return null + } + + try { + const model = String.fromCharCode(data[0] & 0x7F) + const modelName = DEVICE_MODEL_MAP[model] + + if (!modelName) { + this.logger.debug(`Unknown device model: ${model} (0x${data[0].toString(16)})`) + return null + } + + // Basic service data structure + const serviceData: BLEServiceData = { + model, + modelName, + rawData: data, + } + + // Parse battery if available (common across most devices) + if (data.length > 2) { + serviceData.battery = data[2] & 0x7F + } + + // Model-specific advertisement parsing for status without active connection + if (model === 'H' && data.length > 1) { + // Bot (WoHand): infer mode/state from status bits + serviceData.mode = (data[1] & 0x80) ? 'switch' : 'press' + serviceData.state = (data[1] & 0x40) !== 0 + } + + if ((model === 'c' || model === '{') && data.length > 4) { + // Curtain/Curtain3 + serviceData.inMotion = (data[1] & 0x40) !== 0 + serviceData.position = Math.min(100, Math.max(0, data[3] & 0x7F)) + serviceData.lightLevel = data[4] & 0x7F + serviceData.calibration = (data[1] & 0x20) !== 0 + if (data.length > 5) { + serviceData.deviceChain = data[5] & 0x03 + } + } + + if ((model === 'o' || model === '\x11') && data.length > 1) { + // Lock / Lock Pro + const lockStatus = data[1] & 0x0F + serviceData.status = lockStatus + serviceData.doorOpen = (data[1] & 0x10) !== 0 + serviceData.calibration = (data[1] & 0x80) !== 0 + serviceData.lockState = lockStatus === 1 + ? 'unlocked' + : lockStatus === 2 + ? 'jammed' + : 'locked' + if (data.length > 3) { + serviceData.sequenceNumber = data[3] + } + } + + if ((model === '\x0D' || model === '\x0E') && data.length > 1) { + // Relay Switch 1PM / Relay Switch 1 + serviceData.state = (data[1] & 0x01) === 0x01 + serviceData.channel2State = (data[1] & 0x02) === 0x02 + if (data.length > 3) { + serviceData.sequenceNumber = data[3] + } + } + + return serviceData + } catch (error) { + this.logger.error('Error parsing service data', error) + return null + } + } + + /** + * Start scanning for devices + */ + async startScan(options: BLEScanOptions = {}): Promise { + await this.ensureNoble() + const { duration = BLE_SCAN_TIMEOUT, active = true } = options + + this.logger.info('Starting BLE scan', { duration, active }) + + if (!this.noble) { + throw new BLENotAvailableError('BLE not available - noble failed to initialize') + } + + if (this.noble.state !== 'poweredOn') { + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + reject(new Error('BLE adapter not ready')) + }, 5000) + + this.once('ready', () => { + clearTimeout(timeout) + resolve() + }) + }) + } + + // Clear previous discoveries if starting fresh + this.discoveredDevices.clear() + this.discoveredModelCache.clear() + + // Start scanning + this.noble.startScanning([], active) + + // Auto-stop after duration + if (duration > 0) { + setTimeout(() => { + if (this.scanning) { + this.stopScan() + } + }, duration) + } + } + + /** + * Stop scanning + */ + stopScan(): void { + if (this.scanning) { + this.noble.stopScanning() + } + } + + /** + * Cleanup all resources + */ + destroy(): void { + this.stopScan() + this.removeNobleHandlers() + this.discoveredDevices.clear() + this.discoveredModelCache.clear() + } + + /** + * Get all discovered devices + */ + getDiscoveredDevices(): BLEAdvertisement[] { + return [...this.discoveredDevices.values()] + } + + /** + * Get discovered device by MAC or BLE ID + */ + getDevice(mac: string, bleId?: string): BLEAdvertisement | undefined { + // Try MAC lookup first + const byMac = this.discoveredDevices.get(normalizeMAC(mac)) + if (byMac) { + return byMac + } + + // Fall back to ID-based lookup + if (bleId) { + return this.discoveredDevices.get(`id:${bleId}`) + } + + return undefined + } + + /** + * Check if currently scanning + */ + isScanning(): boolean { + return this.scanning + } + + /** + * Wait for specific device + */ + async waitForDevice(mac: string, timeoutMs = BLE_SCAN_TIMEOUT, bleId?: string): Promise { + const normalizedMac = normalizeMAC(mac) + + // Check if already discovered (try MAC first, then ID) + const existing = this.discoveredDevices.get(normalizedMac) || (bleId ? this.discoveredDevices.get(`id:${bleId}`) : undefined) + if (existing) { + return existing + } + + // Wait for discovery + return withTimeout( + new Promise((resolve) => { + const handler = (advertisement: BLEAdvertisement) => { + // Match by address (if available) or by ID + const matches = (advertisement.address && normalizeMAC(advertisement.address) === normalizedMac) + || (bleId && advertisement.id === bleId) + if (matches) { + this.off('discover', handler) + resolve(advertisement) + } + } + this.on('discover', handler) + }), + timeoutMs, + `Device ${mac} not found within ${timeoutMs}ms`, + ) + } +} + +/** + * BLE Connection for communicating with SwitchBot devices + */ +export class BLEConnection { + private noble: any + private logger: Logger + private connections: Map = new Map() // Map of MAC -> Peripheral + private characteristics: Map = new Map() + private disconnectTimers: Map = new Map() + private operationLocks: Map> = new Map() + private encryptionConfig: Map = new Map() + private notificationHandlers: Map void>> = new Map() + private persistentConnectionMs = 8500 + private noblePromise: Promise | null = null + + // Notification handling + private notificationFutures: Map void, reject: (err: Error) => void, timer: NodeJS.Timeout }> = new Map() + + // Expected disconnect tracking + private expectedDisconnects: Set = new Set() + /** + * Mark the next disconnect for this MAC as expected + */ + markExpectedDisconnect(mac: string): void { + this.expectedDisconnects.add(normalizeMAC(mac)) + } + + constructor(options: { noble?: any, logLevel?: number, logger?: Logger } = {}) { + this.logger = options.logger ?? new Logger('BLEConnection', options.logLevel) + this.noble = options.noble + + if (!this.noble) { + this.initializeNoble().catch((error) => { + this.logger.error('Failed to initialize Noble', error) + }) + } + } + + /** + * Initialize Noble lazily + */ + private async initializeNoble(): Promise { + if (this.noble) { + return + } + + if (this.noblePromise) { + // Wait for existing initialization to complete + this.noble = await this.noblePromise + return + } + + this.noblePromise = (async () => { + try { + const module = await import('@stoprocent/noble') + return module.default + } catch (error) { + throw new BLENotAvailableError('BLE not supported on this platform or @stoprocent/noble not installed') + } + })() + + try { + this.noble = await this.noblePromise + } catch (error) { + throw new BLENotAvailableError('BLE not supported on this platform or @stoprocent/noble not installed') + } + } + + /** + * Ensure Noble is loaded before operations + */ + private async ensureNoble(): Promise { + if (!this.noble) { + await this.initializeNoble() + } + + if (!this.noble) { + throw new BLENotAvailableError('BLE not available - noble failed to initialize') + } + } + + private async withMacLock(mac: string, fn: () => Promise): Promise { + const normalizedMac = normalizeMAC(mac) + const previousLock = this.operationLocks.get(normalizedMac) ?? Promise.resolve() + let releaseCurrent: () => void = () => {} + const currentLock = new Promise((resolve) => { + releaseCurrent = resolve + }) + + const chainedLock = previousLock.then(() => currentLock) + this.operationLocks.set(normalizedMac, chainedLock) + await previousLock + + try { + return await fn() + } finally { + releaseCurrent() + if (this.operationLocks.get(normalizedMac) === chainedLock) { + this.operationLocks.delete(normalizedMac) + } + } + } + + private clearDisconnectTimer(mac: string): void { + const existingTimer = this.disconnectTimers.get(mac) + if (existingTimer) { + clearTimeout(existingTimer) + this.disconnectTimers.delete(mac) + } + } + + private scheduleDisconnect(mac: string): void { + this.clearDisconnectTimer(mac) + const timer = setTimeout(() => { + this.disconnect(mac).catch((error) => { + this.logger.debug(`Auto-disconnect failed for ${mac}`, error) + }) + }, this.persistentConnectionMs) + this.disconnectTimers.set(mac, timer) + } + + setPersistentConnectionTimeout(timeoutMs: number): void { + this.persistentConnectionMs = Math.max(1000, timeoutMs) + } + + setEncryption(mac: string, keyHex: string, ivHex: string, mode: 'auto' | 'ctr' | 'gcm' = 'auto'): void { + const normalizedMac = normalizeMAC(mac) + const key = Buffer.from(keyHex, 'hex') + const iv = Buffer.from(ivHex, 'hex') + + if (key.length !== 16) { + throw new CommandFailedError('Invalid BLE encryption key length (expected 16 bytes)', 'ble') + } + + const resolvedMode: 'ctr' | 'gcm' = mode === 'auto' + ? (iv.length === 12 ? 'gcm' : 'ctr') + : mode + + const expectedIvLength = resolvedMode === 'gcm' ? 12 : 16 + if (iv.length !== expectedIvLength) { + throw new CommandFailedError(`Invalid IV length for ${resolvedMode.toUpperCase()} mode`, 'ble') + } + + this.encryptionConfig.set(normalizedMac, { key, iv: Buffer.from(iv), mode: resolvedMode }) + } + + clearEncryption(mac: string): void { + this.encryptionConfig.delete(normalizeMAC(mac)) + } + + private incrementIv(iv: Buffer): Buffer { + const nextIv = Buffer.from(iv) + for (let i = nextIv.length - 1; i >= 0; i--) { + if ((nextIv[i] ?? 0) === 0xFF) { + nextIv[i] = 0x00 + } else { + nextIv[i] = (nextIv[i] ?? 0) + 1 + break + } + } + return nextIv + } + + private encryptIfConfigured(mac: string, data: Buffer): Buffer { + const normalizedMac = normalizeMAC(mac) + const config = this.encryptionConfig.get(normalizedMac) + + if (!config) { + return data + } + + if (config.mode === 'gcm') { + const cipher = createCipheriv('aes-128-gcm', config.key, config.iv) + const encrypted = Buffer.concat([cipher.update(data), cipher.final()]) + const tag = cipher.getAuthTag().subarray(0, 2) + this.encryptionConfig.set(normalizedMac, { + ...config, + iv: this.incrementIv(config.iv), + }) + return Buffer.concat([encrypted, tag]) + } + + const cipher = createCipheriv('aes-128-ctr', config.key, config.iv) + return Buffer.concat([cipher.update(data), cipher.final()]) + } + + private validateCommandResult(response: Buffer, mac: string): void { + if (!response || response.length === 0) { + throw new CommandFailedError(`Empty BLE response from ${mac}`, 'ble') + } + + if (response.includes(0x07)) { + throw new CommandFailedError(`BLE command rejected by ${mac}: password required`, 'ble') + } + + if (response.includes(0x09)) { + throw new CommandFailedError(`BLE command rejected by ${mac}: password incorrect`, 'ble') + } + + const acknowledged = response.some(byte => byte === 0x01 || byte === 0x05 || byte === 0x06) + if (!acknowledged) { + throw new CommandFailedError(`Unexpected BLE response from ${mac}: ${response.toString('hex')}`, 'ble') + } + } + + async sendCommand( + mac: string, + data: Buffer, + options: { + expectResponse?: boolean + validateResponse?: boolean + responseTimeoutMs?: number + expectNotification?: boolean + notificationTimeoutMs?: number + } = {}, + ): Promise { + const normalizedMac = normalizeMAC(mac) + const { + expectResponse = true, + validateResponse = true, + responseTimeoutMs = 1200, + expectNotification = false, + notificationTimeoutMs = 5000, + } = options + + return this.withMacLock(normalizedMac, async () => { + const payload = this.encryptIfConfigured(normalizedMac, data) + await this.write(normalizedMac, payload) + + if (expectNotification) { + // DEBUG: Log future creation + this.logger.debug(`[DEBUG] Creating notification future for ${normalizedMac}`) + // Wait for notification (per-command future) + return await new Promise((resolve, reject) => { + if (this.notificationFutures.has(normalizedMac)) { + this.logger.warn(`Notification future already exists for ${normalizedMac}, overwriting`) + const prev = this.notificationFutures.get(normalizedMac) + if (prev) { + clearTimeout(prev.timer) + } + } + const timer = setTimeout(() => { + this.logger.debug(`[DEBUG] Notification future timed out for ${normalizedMac}`) + this.notificationFutures.delete(normalizedMac) + reject(new Error(`Notification timeout (${notificationTimeoutMs}ms) for ${normalizedMac}`)) + }, notificationTimeoutMs) + this.notificationFutures.set(normalizedMac, { resolve, reject, timer }) + // TEST HOOK: Notify when the notification future is set + if (typeof (this as any)._onNotificationFutureSet === 'function') { + (this as any)._onNotificationFutureSet(normalizedMac) + } + this.logger.debug(`[DEBUG] notificationFutures after set: ${[...this.notificationFutures.keys()].join(',')}`) + }) + } + + if (!expectResponse && !validateResponse) { + return undefined + } + + const response = await withTimeout( + this.read(normalizedMac), + responseTimeoutMs, + `BLE response timeout from ${normalizedMac}`, + ) + + if (validateResponse) { + this.validateCommandResult(response, normalizedMac) + } + + return response + }) + } + + async subscribeNotifications(mac: string, handler: (payload: Buffer) => void): Promise { + const normalizedMac = normalizeMAC(mac) + + if (!this.connections.has(normalizedMac)) { + await this.connect(normalizedMac) + } + + const chars = this.characteristics.get(normalizedMac) + if (!chars?.notify) { + throw new CommandFailedError(`Notify characteristic not available for ${normalizedMac}`, 'ble') + } + + if (!this.notificationHandlers.has(normalizedMac)) { + this.notificationHandlers.set(normalizedMac, new Set()) + + if (typeof chars.notify.on === 'function') { + chars.notify.on('data', (payload: Buffer) => { + // DEBUG: Log notification future state + this.logger.debug(`[DEBUG] notifyChar handler called for ${normalizedMac}`) + this.logger.debug(`[DEBUG] notificationFutures keys at handler: ${[...this.notificationFutures.keys()].join(',')}`) + const future = this.notificationFutures.get(normalizedMac) + if (future) { + this.logger.debug(`[DEBUG] notificationFutures present, resolving as solicited`) + clearTimeout(future.timer) + this.notificationFutures.delete(normalizedMac) + this.logger.debug(`[DEBUG] notificationFutures after delete: ${[...this.notificationFutures.keys()].join(',')}`) + future.resolve(payload) + return + } + this.logger.debug(`[DEBUG] unsolicited notification branch`) + this.logger.debug(`[DEBUG] about to call logger.info for unsolicited notification`) + this.logger.info(`Unsolicited notification from ${normalizedMac}: ${payload.toString('hex')}`) + this.logger.debug(`[DEBUG] after logger.info for unsolicited notification`) + const handlers = this.notificationHandlers.get(normalizedMac) + if (!handlers) { + return + } + for (const listener of handlers) { + listener(payload) + } + }) + } + } + + this.notificationHandlers.get(normalizedMac)!.add(handler) + + if (typeof chars.notify.subscribe === 'function') { + await new Promise((resolve, reject) => { + chars.notify.subscribe((error: Error) => { + if (error) { + reject(error) + } else { + resolve() + } + }) + }) + } + } + + unsubscribeNotifications(mac: string, handler: (payload: Buffer) => void): void { + const normalizedMac = normalizeMAC(mac) + const handlers = this.notificationHandlers.get(normalizedMac) + if (!handlers) { + return + } + + handlers.delete(handler) + if (handlers.size === 0) { + this.notificationHandlers.delete(normalizedMac) + } + } + + /** + * Connect to a device + */ + async connect(mac: string): Promise { + await this.ensureNoble() + const normalizedMac = normalizeMAC(mac) + + // Already connected? + if (this.connections.has(normalizedMac)) { + this.clearDisconnectTimer(normalizedMac) + this.logger.debug(`Already connected to ${mac}`) + return + } + + this.logger.info(`Connecting to ${mac}`) + + // Find peripheral (by address or ID) + const peripherals = await this.noble.peripherals || [] + let peripheral: any + + // Try to find by normalized MAC first + if (mac.startsWith('id:')) { + // ID-based lookup: extract the ID and find by peripheral.id + const bleId = mac.substring(3) + // Look through peripherals to find matching ID + peripheral = peripherals.find((p: any) => p.id === bleId) + } else { + // MAC-based lookup + peripheral = peripherals.find((p: any) => p.address && normalizeMAC(p.address) === normalizedMac) + } + + if (!peripheral) { + throw new DeviceNotFoundError(mac) + } + + // Connect + await withTimeout( + new Promise((resolve, reject) => { + peripheral.connect((error: Error) => { + if (error) { + reject(error) + } else { + resolve() + } + }) + }), + BLE_CONNECT_TIMEOUT, + `Connection to ${mac} timed out`, + ) + + this.connections.set(normalizedMac, peripheral) + this.clearDisconnectTimer(normalizedMac) + this.logger.info(`Connected to ${mac}`) + + // Discover characteristics (may throw) + try { + await this.discoverCharacteristics(normalizedMac, peripheral) + } catch (error) { + // Clean up partial connection if characteristic discovery fails + this.connections.delete(normalizedMac) + this.characteristics.delete(normalizedMac) + + // Best effort disconnect to avoid leaked active BLE links + await new Promise((resolve) => { + peripheral.disconnect(() => resolve()) + }) + + throw error + } + } + + /** + * Discover service characteristics + */ + private async discoverCharacteristics(mac: string, peripheral: any): Promise { + const { characteristics } = await withTimeout( + new Promise((resolve, reject) => { + peripheral.discoverSomeServicesAndCharacteristics( + [BLE_SERVICE_UUID], + [BLE_WRITE_CHARACTERISTIC_UUID, BLE_NOTIFY_CHARACTERISTIC_UUID], + (error: Error, services: any[], chars: any[]) => { + if (error) { + reject(error) + } else { + resolve({ services, characteristics: chars }) + } + }, + ) + }), + BLE_CONNECT_TIMEOUT, + 'Characteristic discovery timed out', + ) + + const writeChar = characteristics.find((c: any) => c.uuid === BLE_WRITE_CHARACTERISTIC_UUID.replace(UUID_DASH_REGEX, '')) + const notifyChar = characteristics.find((c: any) => c.uuid === BLE_NOTIFY_CHARACTERISTIC_UUID.replace(UUID_DASH_REGEX, '')) + + if (!writeChar || !notifyChar) { + throw new Error('Required characteristics not found') + } + + this.characteristics.set(mac, { write: writeChar, notify: notifyChar }) + this.logger.debug(`Characteristics discovered for ${mac}`) + } + + /** + * Disconnect from a device + */ + async disconnect(mac: string): Promise { + const normalizedMac = normalizeMAC(mac) + const peripheral = this.connections.get(normalizedMac) + this.clearDisconnectTimer(normalizedMac) + // Reset encryption state (IV, cipher, mode) for this device + this.clearEncryption(normalizedMac) + this.notificationHandlers.delete(normalizedMac) + + const wasExpected = this.expectedDisconnects.has(normalizedMac) + if (wasExpected) { + this.expectedDisconnects.delete(normalizedMac) + } + + if (!peripheral) { + if (!wasExpected) { + this.logger.warn(`Unexpected disconnect: peripheral not found for ${mac}`) + } else { + this.logger.info(`Expected disconnect: peripheral not found for ${mac}`) + } + return + } + + await new Promise((resolve) => { + peripheral.disconnect(() => { + this.connections.delete(normalizedMac) + this.characteristics.delete(normalizedMac) + if (wasExpected) { + this.logger.info(`Expected disconnect from ${mac}`) + } else { + this.logger.warn(`Unexpected disconnect from ${mac}`) + } + resolve() + }) + }) + } + + /** + * Write data to device + */ + async write(mac: string, data: Buffer): Promise { + const normalizedMac = normalizeMAC(mac) + + // Ensure connected + if (!this.connections.has(normalizedMac)) { + await this.connect(mac) + } + + let chars = this.characteristics.get(normalizedMac) + if (!chars) { + await this.discoverCharacteristics(normalizedMac, this.connections.get(normalizedMac)) + chars = this.characteristics.get(normalizedMac) + if (!chars) { + throw new Error(`Characteristics not available for ${mac}`) + } + } + + this.logger.debug(`Writing to ${mac}:`, data.toString('hex')) + + try { + await withTimeout( + new Promise((resolve, reject) => { + (chars!.write).write(data, false, (error: Error | null) => { + if (error) { + reject(error) + } else { + this.scheduleDisconnect(normalizedMac) + resolve() + } + }) + }), + BLE_COMMAND_TIMEOUT, + 'Write operation timed out', + ) + } catch (err: any) { + // If error is characteristic-related, clear cache and retry once + if (CHARACTERISTIC_REGEX.test(err?.message || '')) { + this.characteristics.delete(normalizedMac) + await this.discoverCharacteristics(normalizedMac, this.connections.get(normalizedMac)) + chars = this.characteristics.get(normalizedMac) + if (!chars) { + throw err + } + // Retry once + await withTimeout( + new Promise((resolve, reject) => { + (chars!.write).write(data, false, (error: Error | null) => { + if (error) { + reject(error) + } else { + this.scheduleDisconnect(normalizedMac) + resolve() + } + }) + }), + BLE_COMMAND_TIMEOUT, + 'Write operation timed out', + ) + } else { + throw err + } + } + } + + /** + * Read data from device + */ + async read(mac: string): Promise { + const normalizedMac = normalizeMAC(mac) + + // Ensure connected + if (!this.connections.has(normalizedMac)) { + await this.connect(mac) + } + + let chars = this.characteristics.get(normalizedMac) + if (!chars) { + await this.discoverCharacteristics(normalizedMac, this.connections.get(normalizedMac)) + chars = this.characteristics.get(normalizedMac) + if (!chars) { + throw new Error(`Characteristics not available for ${mac}`) + } + } + + this.logger.debug(`Reading from ${mac}`) + + try { + return await withTimeout( + new Promise((resolve, reject) => { + (chars!.notify).read((error: Error, data: Buffer) => { + if (error) { + reject(error) + } else { + this.scheduleDisconnect(normalizedMac) + resolve(data) + } + }) + }), + BLE_COMMAND_TIMEOUT, + 'Read operation timed out', + ) + } catch (err: any) { + // If error is characteristic-related, clear cache and retry once + if (CHARACTERISTIC_REGEX.test(err?.message || '')) { + this.characteristics.delete(normalizedMac) + await this.discoverCharacteristics(normalizedMac, this.connections.get(normalizedMac)) + chars = this.characteristics.get(normalizedMac) + if (!chars) { + throw err + } + // Retry once + return await withTimeout( + new Promise((resolve, reject) => { + (chars!.notify).read((error: Error, data: Buffer) => { + if (error) { + reject(error) + } else { + this.scheduleDisconnect(normalizedMac) + resolve(data) + } + }) + }), + BLE_COMMAND_TIMEOUT, + 'Read operation timed out', + ) + } else { + throw err + } + } + } + + /** + * Check if connected to device + */ + isConnected(mac: string): boolean { + return this.connections.has(normalizeMAC(mac)) + } + + /** + * Disconnect all devices + */ + async disconnectAll(): Promise { + const macs = [...this.connections.keys()] + await Promise.all(macs.map(mac => this.disconnect(mac))) + } + + /** + * Get connected device count + */ + getConnectionCount(): number { + return this.connections.size + } +} diff --git a/src/device.test.ts b/src/device.test.ts deleted file mode 100644 index 97623628..00000000 --- a/src/device.test.ts +++ /dev/null @@ -1,386 +0,0 @@ -import { Buffer } from 'node:buffer' - -import { describe, expect, it } from 'vitest' - -import { Advertising, ErrorUtils, LogLevel, ValidationUtils, WoAirPurifier, WoPlugMiniEU } from './device.js' - -describe('validationUtils', () => { - describe('validatePercentage', () => { - it('should accept valid percentages', () => { - expect(() => ValidationUtils.validatePercentage(0)).not.toThrow() - expect(() => ValidationUtils.validatePercentage(50)).not.toThrow() - expect(() => ValidationUtils.validatePercentage(100)).not.toThrow() - }) - - it('should reject invalid percentages', () => { - expect(() => ValidationUtils.validatePercentage(-1)).toThrow('must be between 0 and 100') - expect(() => ValidationUtils.validatePercentage(101)).toThrow('must be between 0 and 100') - expect(() => ValidationUtils.validatePercentage(Number.NaN)).toThrow('must be a valid number') - }) - - it('should reject non-numbers', () => { - expect(() => ValidationUtils.validatePercentage('50' as any)).toThrow('must be a valid number') - expect(() => ValidationUtils.validatePercentage(null as any)).toThrow('must be a valid number') - }) - }) - - describe('validateRGB', () => { - it('should accept valid RGB values', () => { - expect(() => ValidationUtils.validateRGB(0)).not.toThrow() - expect(() => ValidationUtils.validateRGB(128)).not.toThrow() - expect(() => ValidationUtils.validateRGB(255)).not.toThrow() - }) - - it('should reject invalid RGB values', () => { - expect(() => ValidationUtils.validateRGB(-1)).toThrow('must be an integer between 0 and 255') - expect(() => ValidationUtils.validateRGB(256)).toThrow('must be an integer between 0 and 255') - expect(() => ValidationUtils.validateRGB(128.5)).toThrow('must be an integer between 0 and 255') - }) - }) - - describe('validateBuffer', () => { - it('should accept valid buffers', () => { - const buffer = Buffer.from([1, 2, 3]) - expect(() => ValidationUtils.validateBuffer(buffer)).not.toThrow() - expect(() => ValidationUtils.validateBuffer(buffer, 3)).not.toThrow() - }) - - it('should reject non-buffers', () => { - expect(() => ValidationUtils.validateBuffer('not a buffer' as any)).toThrow('must be a Buffer instance') - expect(() => ValidationUtils.validateBuffer(null as any)).toThrow('must be a Buffer instance') - }) - - it('should validate buffer length', () => { - const buffer = Buffer.from([1, 2, 3]) - expect(() => ValidationUtils.validateBuffer(buffer, 2)).toThrow('must have exactly 2 bytes') - expect(() => ValidationUtils.validateBuffer(buffer, 4)).toThrow('must have exactly 4 bytes') - }) - }) - - describe('validateString', () => { - it('should accept valid strings', () => { - expect(() => ValidationUtils.validateString('hello')).not.toThrow() - expect(() => ValidationUtils.validateString('test', 'param', 1, 10)).not.toThrow() - }) - - it('should reject non-strings', () => { - expect(() => ValidationUtils.validateString(123 as any)).toThrow('must be a string') - expect(() => ValidationUtils.validateString(null as any)).toThrow('must be a string') - }) - - it('should validate string length', () => { - expect(() => ValidationUtils.validateString('')).toThrow('must have at least 1 character') - expect(() => ValidationUtils.validateString('too long', 'param', 1, 5)).toThrow('must have at most 5 character') - }) - }) - - describe('validateRange', () => { - it('should accept values in range', () => { - expect(() => ValidationUtils.validateRange(5, 0, 10)).not.toThrow() - expect(() => ValidationUtils.validateRange(0, 0, 10)).not.toThrow() - expect(() => ValidationUtils.validateRange(10, 0, 10)).not.toThrow() - }) - - it('should reject values out of range', () => { - expect(() => ValidationUtils.validateRange(-1, 0, 10)).toThrow('must be between 0 and 10') - expect(() => ValidationUtils.validateRange(11, 0, 10)).toThrow('must be between 0 and 10') - }) - - it('should validate integers when required', () => { - expect(() => ValidationUtils.validateRange(5, 0, 10, 'value', true)).not.toThrow() - expect(() => ValidationUtils.validateRange(5.5, 0, 10, 'value', true)).toThrow('must be an integer') - }) - }) - - describe('validateMacAddress', () => { - it('should accept valid MAC addresses', () => { - expect(() => ValidationUtils.validateMacAddress('AA:BB:CC:DD:EE:FF')).not.toThrow() - expect(() => ValidationUtils.validateMacAddress('aa:bb:cc:dd:ee:ff')).not.toThrow() - expect(() => ValidationUtils.validateMacAddress('AA-BB-CC-DD-EE-FF')).not.toThrow() - expect(() => ValidationUtils.validateMacAddress('aabbccddeeff')).not.toThrow() - }) - - it('should reject invalid MAC addresses', () => { - expect(() => ValidationUtils.validateMacAddress('invalid')).toThrow('must be a valid MAC address format') - expect(() => ValidationUtils.validateMacAddress('GG:BB:CC:DD:EE:FF')).toThrow('must be a valid MAC address format') - }) - }) - - describe('validateEnum', () => { - it('should accept valid enum values', () => { - const allowed = ['red', 'green', 'blue'] as const - expect(() => ValidationUtils.validateEnum('red', allowed)).not.toThrow() - expect(() => ValidationUtils.validateEnum('green', allowed)).not.toThrow() - }) - - it('should reject invalid enum values', () => { - const allowed = ['red', 'green', 'blue'] as const - expect(() => ValidationUtils.validateEnum('yellow', allowed)).toThrow('must be one of: red, green, blue') - }) - }) -}) - -describe('errorUtils', () => { - describe('createTimeoutError', () => { - it('should create descriptive timeout errors', () => { - const error = ErrorUtils.createTimeoutError('connect', 5000) - expect(error.message).toBe('Operation \'connect\' timed out after 5000ms') - }) - }) - - describe('createConnectionError', () => { - it('should create connection errors with device context', () => { - const error = ErrorUtils.createConnectionError('device123') - expect(error.message).toBe('Failed to connect to device device123') - }) - - it('should include cause if provided', () => { - const cause = new Error('Network unavailable') - const error = ErrorUtils.createConnectionError('device123', cause) - expect(error.message).toBe('Failed to connect to device device123: Network unavailable') - }) - }) - - describe('createCommandError', () => { - it('should create command errors with context', () => { - const error = ErrorUtils.createCommandError('turnOn', 'device123') - expect(error.message).toBe('Command \'turnOn\' failed for device device123') - }) - }) - - describe('withTimeout', () => { - it('should resolve when operation completes within timeout', async () => { - const fastOperation = Promise.resolve('success') - const result = await ErrorUtils.withTimeout(fastOperation, 1000, 'test') - expect(result).toBe('success') - }) - - it('should reject when operation exceeds timeout', async () => { - const slowOperation = new Promise(resolve => setTimeout(resolve, 100)) - await expect(ErrorUtils.withTimeout(slowOperation, 50, 'test')) - .rejects - .toThrow('Operation \'test\' timed out after 50ms') - }) - }) -}) - -describe('logLevel', () => { - it('should export all log levels', () => { - expect(LogLevel.SUCCESS).toBe('success') - expect(LogLevel.DEBUGSUCCESS).toBe('debugsuccess') - expect(LogLevel.WARN).toBe('warn') - expect(LogLevel.DEBUGWARN).toBe('debugwarn') - expect(LogLevel.ERROR).toBe('error') - expect(LogLevel.DEBUGERROR).toBe('debugerror') - expect(LogLevel.DEBUG).toBe('debug') - expect(LogLevel.INFO).toBe('info') - }) -}) - -describe('advertising', () => { - describe('parse', () => { - it('should parse Air Purifier with minimal serviceData', async () => { - // Air Purifier devices have minimal serviceData (only model byte) - // but all actual data in manufacturerData - const peripheral = { - id: '3c84277658fe', - address: '3c:84:27:76:8c:fe', - rssi: -65, - advertisement: { - serviceData: [ - { - uuid: 'cba20d00224d11e69fb80002a5d5c51b', - data: Buffer.from('+'), // Only model byte for Air Purifier - }, - ], - manufacturerData: Buffer.from([ - 0x59, 0x00, 0x12, 0x34, 0x56, 0x78, // Header - 0x01, // sequenceNumber - 0x80 | 0x02, // isOn=true, mode=2 - 0x04 | 0x00, // isAqiValid=true, childLock=false - 0x50, // speed=80 - 0x02, // aqiLevelRaw=1 (good) - 0x00, 0x64, // workTime=100 - 0x00, // errCode=0 - ]), - }, - } as any - - const emitLog = () => {} - const result = await Advertising.parse(peripheral, emitLog) - - expect(result).not.toBeNull() - expect(result?.serviceData.model).toBe('+') - expect(result?.serviceData.modelName).toBe('WoAirPurifier') - // Type-safe property access - if (result && 'isOn' in result.serviceData) { - expect(result.serviceData.isOn).toBe(true) - expect(result.serviceData.speed).toBe(80) - expect(result.serviceData.aqi_level).toBe('good') - } - }) - - it('should return null when serviceData is missing', async () => { - const peripheral = { - id: 'test', - address: 'aa:bb:cc:dd:ee:ff', - rssi: -50, - advertisement: { - serviceData: [], - }, - } as any - - const emitLog = () => {} - const result = await Advertising.parse(peripheral, emitLog) - - expect(result).toBeNull() - }) - - it('should return null when neither serviceData nor manufacturerData has sufficient data', async () => { - const peripheral = { - id: 'test', - address: 'aa:bb:cc:dd:ee:ff', - rssi: -50, - advertisement: { - serviceData: [ - { - uuid: 'test', - data: Buffer.from('X'), // Only 1 byte - }, - ], - manufacturerData: Buffer.from([0x01]), // Only 1 byte - }, - } as any - - const emitLog = () => {} - const result = await Advertising.parse(peripheral, emitLog) - - expect(result).toBeNull() - }) - }) - - describe('parseServiceData', () => { - it('should parse Air Purifier service data correctly', () => { - const serviceData = Buffer.from('+') - const manufacturerData = Buffer.from([ - 0x59, 0x00, 0x12, 0x34, 0x56, 0x78, - 0x01, // sequenceNumber - 0x80 | 0x01, // isOn=true, mode=1 (manual levels) - 0x04 | 0x02, // isAqiValid=true, childLock=true - 0x42, // speed=66 (level_2) - 0x04, // aqiLevelRaw=2 (fair) - 0x01, 0x00, // workTime=256 - 0x01, // errCode=1 - ]) - - const emitLog = () => {} - const result = WoAirPurifier.parseServiceData(serviceData, manufacturerData, emitLog) - - expect(result).not.toBeNull() - expect(result?.model).toBe('+') - expect(result?.modelName).toBe('WoAirPurifier') - expect(result?.isOn).toBe(true) - expect(result?.mode).toBe('level_2') - expect(result?.speed).toBe(66) - expect(result?.aqi_level).toBe('fair') - expect(result?.isAqiValid).toBe(true) - expect(result?.child_lock).toBe(true) - expect(result?.filter_element_working_time).toBe(256) - expect(result?.err_code).toBe(1) - expect(result?.sequence_number).toBe(1) - }) - - it('should parse Plug Mini EU service data correctly', async () => { - // bytes 0-8: header/MAC/sequence (unused by parser), bytes 9-13: state/flags/rssi/power - const manufacturerData = Buffer.from([ - 0x09, 0x69, // UUID - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // MAC - 0x01, // sequence number - 0x80, // byte9: state=on - 0x07, // byte10: delay=1, timer=1, syncUtcTime=1 - 0x3C, // byte11: wifiRssi=60 - 0x83, // byte12: overload=1, power MSB=3 - 0xE8, // byte13: power LSB=232 => currentPower=(3*256+232)/10=100.0W - ]) - - const emitLog = () => {} - const result = await WoPlugMiniEU.parseServiceData(manufacturerData, emitLog) - - expect(result).not.toBeNull() - expect(result?.model).toBe('l') - expect(result?.modelName).toBe('WoPlugMini') - expect(result?.state).toBe('on') - expect(result?.delay).toBe(true) - expect(result?.timer).toBe(true) - expect(result?.syncUtcTime).toBe(true) - expect(result?.wifiRssi).toBe(60) - expect(result?.overload).toBe(true) - expect(result?.currentPower).toBe(100.0) - }) - - it('should parse Plug Mini EU state=off correctly', async () => { - const manufacturerData = Buffer.from([ - 0x09, 0x69, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, - 0x00, // byte9: state=off - 0x00, // byte10: no flags - 0x00, // byte11: wifiRssi=0 - 0x00, // byte12: no overload, power MSB=0 - 0x00, // byte13: power LSB=0 - ]) - - const emitLog = () => {} - const result = await WoPlugMiniEU.parseServiceData(manufacturerData, emitLog) - - expect(result).not.toBeNull() - expect(result?.state).toBe('off') - expect(result?.delay).toBe(false) - expect(result?.overload).toBe(false) - expect(result?.currentPower).toBe(0) - }) - - it('should return null when Plug Mini EU manufacturerData length is not 14', async () => { - const manufacturerData = Buffer.from([0x01, 0x02, 0x03]) - const errors: string[] = [] - const emitLog = (level: string, msg: string) => { errors.push(msg) } - - const result = await WoPlugMiniEU.parseServiceData(manufacturerData, emitLog) - - expect(result).toBeNull() - expect(errors.length).toBeGreaterThan(0) - expect(errors[0]).toContain('should be 14') - }) - - it('should route Plug Mini EU via Advertising.parse', async () => { - const peripheral = { - id: 'aabbccddee01', - address: 'aa:bb:cc:dd:ee:01', - rssi: -70, - advertisement: { - serviceData: [ - { - uuid: 'fd3d', - data: Buffer.from('l'), // PlugMiniEU model byte - }, - ], - manufacturerData: Buffer.from([ - 0x09, 0x69, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x01, // sequence - 0x80, // state=on - 0x00, // flags - 0x28, // wifiRssi=40 - 0x00, // no overload, power=0 - 0x00, - ]), - }, - } as any - - const emitLog = () => {} - const result = await Advertising.parse(peripheral, emitLog) - - expect(result).not.toBeNull() - expect(result?.serviceData.model).toBe('l') - expect(result?.serviceData.modelName).toBe('WoPlugMini') - }) - }) -}) diff --git a/src/device.ts b/src/device.ts deleted file mode 100644 index 497999f4..00000000 --- a/src/device.ts +++ /dev/null @@ -1,4257 +0,0 @@ -/* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. - * - * device.ts: Switchbot BLE API registration. - */ -import type { Characteristic, Noble, Peripheral, Service } from '@stoprocent/noble' - -import type { airPurifierServiceData, airPurifierTableServiceData, batteryCirculatorFanServiceData, blindTiltServiceData, botServiceData, ceilingLightProServiceData, ceilingLightServiceData, colorBulbServiceData, contactSensorServiceData, curtain3ServiceData, curtainServiceData, hub2ServiceData, hub3ServiceData, humidifier2ServiceData, humidifierServiceData, keypadDetectorServiceData, lockProServiceData, lockServiceData, meterPlusServiceData, meterProCO2ServiceData, meterProServiceData, meterServiceData, motionSensorServiceData, outdoorMeterServiceData, plugMiniEUServiceData, plugMiniJPServiceData, plugMiniUSServiceData, presenceSensorServiceData, relaySwitch1PMServiceData, relaySwitch1ServiceData, remoteServiceData, robotVacuumCleanerServiceData, stripLightServiceData, waterLeakDetectorServiceData } from './types/ble.js' - -import { Buffer } from 'node:buffer' -import * as Crypto from 'node:crypto' -import { EventEmitter } from 'node:events' - -import { CHAR_UUID_DEVICE, CHAR_UUID_NOTIFY, CHAR_UUID_WRITE, READ_TIMEOUT_MSEC, SERV_UUID_PRIMARY, WoSmartLockCommands, WoSmartLockProCommands, WRITE_TIMEOUT_MSEC } from './settings.js' - -/** - * Command constants for various SwitchBot devices. - * Using readonly arrays to ensure immutability and better type safety. - */ -const DEVICE_COMMANDS = { - BLIND_TILT: { - OPEN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x32] as const, - CLOSE_UP: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64] as const, - CLOSE_DOWN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00] as const, - PAUSE: [0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF] as const, - }, - BULB: { - BASE: [0x57, 0x0F, 0x47, 0x01] as const, - READ_STATE: [0x57, 0x0F, 0x48, 0x01] as const, - TURN_ON: [0x01, 0x01] as const, - TURN_OFF: [0x01, 0x02] as const, - SET_BRIGHTNESS: [0x02, 0x14] as const, - SET_COLOR_TEMP: [0x02, 0x17] as const, - SET_RGB: [0x02, 0x12] as const, - }, - HUMIDIFIER: { - HEADER: '5701' as const, - TURN_ON: '570101' as const, - TURN_OFF: '570102' as const, - INCREASE: '570103' as const, - DECREASE: '570104' as const, - SET_AUTO_MODE: '570105' as const, - SET_MANUAL_MODE: '570106' as const, - }, - AIR_PURIFIER: { - TURN_ON: [0x57, 0x01, 0x01] as const, - TURN_OFF: [0x57, 0x01, 0x02] as const, - SET_MODE: [0x57, 0x02] as const, - SET_SPEED: [0x57, 0x03] as const, - }, - // Common commands used across multiple devices - COMMON: { - POWER_ON: [0x57, 0x01, 0x01] as const, - POWER_OFF: [0x57, 0x01, 0x02] as const, - }, -} as const - -/** - * Air quality level constants for air purifier devices. - */ -const AIR_QUALITY_LEVELS = { - EXCELLENT: 'excellent', - GOOD: 'good', - FAIR: 'fair', - POOR: 'poor', -} as const - -/** - * Air purifier mode constants. - */ -const AIR_PURIFIER_MODES = { - MANUAL: 'manual', - AUTO: 'auto', - SLEEP: 'sleep', - LEVEL_1: 'level_1', - LEVEL_2: 'level_2', - LEVEL_3: 'level_3', -} as const - -// Legacy constants for backward compatibility -const BLIND_TILT_COMMANDS = DEVICE_COMMANDS.BLIND_TILT -const BULB_COMMANDS = DEVICE_COMMANDS.BULB -const HUMIDIFIER_COMMAND_HEADER = DEVICE_COMMANDS.HUMIDIFIER.HEADER -const TURN_ON_KEY = DEVICE_COMMANDS.HUMIDIFIER.TURN_ON -const TURN_OFF_KEY = DEVICE_COMMANDS.HUMIDIFIER.TURN_OFF -const INCREASE_KEY = DEVICE_COMMANDS.HUMIDIFIER.INCREASE -const DECREASE_KEY = DEVICE_COMMANDS.HUMIDIFIER.DECREASE -const SET_AUTO_MODE_KEY = DEVICE_COMMANDS.HUMIDIFIER.SET_AUTO_MODE -const SET_MANUAL_MODE_KEY = DEVICE_COMMANDS.HUMIDIFIER.SET_MANUAL_MODE - -export type MacAddress = string - -export interface ad { - id: string - address: string - rssi: number - serviceData: airPurifierServiceData | airPurifierTableServiceData | botServiceData | colorBulbServiceData | contactSensorServiceData | curtainServiceData | curtain3ServiceData | stripLightServiceData | lockServiceData | lockProServiceData | meterServiceData | meterPlusServiceData | meterProServiceData | meterProCO2ServiceData | motionSensorServiceData | presenceSensorServiceData | outdoorMeterServiceData | plugMiniUSServiceData | plugMiniJPServiceData | plugMiniEUServiceData | blindTiltServiceData | ceilingLightServiceData | ceilingLightProServiceData | hub2ServiceData | hub3ServiceData | batteryCirculatorFanServiceData | waterLeakDetectorServiceData | humidifierServiceData | humidifier2ServiceData | robotVacuumCleanerServiceData | keypadDetectorServiceData | relaySwitch1PMServiceData | relaySwitch1ServiceData | remoteServiceData - [key: string]: unknown -} - -export type ondiscover = (device: SwitchbotDevice) => Promise | void - -export type onadvertisement = (ad: ad) => Promise | void - -interface DeviceInfo { - Model: SwitchBotModel - BLEModel: SwitchBotBLEModel - BLEModelName: SwitchBotBLEModelName - ModelFriendlyName: SwitchBotBLEModelFriendlyName -} - -export declare interface SwitchBotBLEDevice { - Bot: DeviceInfo - Curtain: DeviceInfo - Curtain3: DeviceInfo - Humidifier: DeviceInfo - Meter: DeviceInfo - MeterPlus: DeviceInfo - MeterPro: DeviceInfo - MeterProCO2: DeviceInfo - Hub2: DeviceInfo - Hub3: DeviceInfo - OutdoorMeter: DeviceInfo - MotionSensor: DeviceInfo - PresenceSensor: DeviceInfo - ContactSensor: DeviceInfo - ColorBulb: DeviceInfo - StripLight: DeviceInfo - PlugMiniUS: DeviceInfo - PlugMiniJP: DeviceInfo - PlugMiniEU: DeviceInfo - Lock: DeviceInfo - LockPro: DeviceInfo - CeilingLight: DeviceInfo - CeilingLightPro: DeviceInfo - BlindTilt: DeviceInfo - Unknown: DeviceInfo - AirPurifier: DeviceInfo - AirPurifierTable: DeviceInfo -} - -export enum SwitchBotModel { - HubMini = 'W0202200', - HubPlus = 'SwitchBot Hub S1', - Hub2 = 'W3202100', - Hub3 = 'W3302100', - Bot = 'SwitchBot S1', - Curtain = 'W0701600', - Curtain3 = 'W2400000', - Humidifier = 'W0801800', - Humidifier2 = 'WXXXXXXX', - Plug = 'SP11', // Currently only available in Japan - Meter = 'SwitchBot MeterTH S1', - MeterPlusJP = 'W2201500', - MeterPlusUS = 'W2301500', - MeterPro = 'W4900000', - MeterProCO2 = 'W4900010', - OutdoorMeter = 'W3400010', - MotionSensor = 'W1101500', - PresenceSensor = 'W8200000', - ContactSensor = 'W1201500', - ColorBulb = 'W1401400', - StripLight = 'W1701100', - PlugMiniUS = 'W1901400/W1901401', - PlugMiniJP = 'W2001400/W2001401', - PlugMiniEU = 'W7732300', - Lock = 'W1601700', - LockPro = 'W3500000', - LockUltra = 'W3600000', - Keypad = 'W2500010', - KeypadTouch = 'W2500020', - K10 = 'K10+', - K10Pro = 'K10+ Pro', - WoSweeper = 'WoSweeper', - WoSweeperMini = 'WoSweeperMini', - RobotVacuumCleanerS1 = 'W3011000', // Currently only available in Japan. - RobotVacuumCleanerS1Plus = 'W3011010', // Currently only available in Japan. - RobotVacuumCleanerS10 = 'W3211800', - Remote = 'Remote', - UniversalRemote = 'UniversalRemote', - CeilingLight = 'W2612230/W2612240', // Currently only available in Japan. - CeilingLightPro = 'W2612210/W2612220', // Currently only available in Japan. - IndoorCam = 'W1301200', - PanTiltCam = 'W1801200', - PanTiltCam2K = 'W3101100', - BlindTilt = 'W2701600', - BatteryCirculatorFan = 'W3800510', - CirculatorFan = 'W3800511', - WaterDetector = 'W4402000', - RelaySwitch1 = 'W5502300', - RelaySwitch1PM = 'W5502310', - Unknown = 'Unknown', - AirPurifier = 'W5302300', - AirPurifierTable = 'W5302310', -} - -export enum SwitchBotBLEModel { - Bot = 'H', - Curtain = 'c', - Curtain3 = '{', - Humidifier = 'e', - Humidifier2 = '#', - Meter = 'T', - MeterPlus = 'i', - MeterPro = '4', - MeterProCO2 = '5', - Hub2 = 'v', - Hub3 = 'V', - OutdoorMeter = 'w', - MotionSensor = 's', - PresenceSensor = 'p', - ContactSensor = 'd', - ColorBulb = 'u', - StripLight = 'r', - PlugMiniUS = 'g', - PlugMiniJP = 'j', // Only available in Japan. - PlugMiniEU = 'l', // Only available in Europe. - Lock = 'o', - LockPro = '$', - LockUltra = 'U', - CeilingLight = 'q', // Currently only available in Japan. - CeilingLightPro = 'n', // Currently only available in Japan. - BlindTilt = 'x', - Leak = '&', - Keypad = 'y', - RelaySwitch1 = ';', - RelaySwitch1PM = '<', - Remote = 'b', - Unknown = 'Unknown', - AirPurifier = '+', - AirPurifierTable = '7', -} - -export enum SwitchBotBLEModelName { - Bot = 'WoHand', - Hub2 = 'WoHub2', - Hub3 = 'WoHub3', - ColorBulb = 'WoBulb', - Curtain = 'WoCurtain', - Curtain3 = 'WoCurtain3', - Humidifier = 'WoHumi', - Humidifier2 = 'WoHumi2', - Meter = 'WoSensorTH', - MeterPlus = 'WoSensorTHPlus', - MeterPro = 'WoSensorTHP', - MeterProCO2 = 'WoSensorTHPc', - Lock = 'WoSmartLock', - LockPro = 'WoSmartLockPro', - LockUltra = 'WoSmartLockUltra', - PresenceSensor = 'WoPresence', - PlugMini = 'WoPlugMini', - StripLight = 'WoStrip', - OutdoorMeter = 'WoIOSensorTH', - ContactSensor = 'WoContact', - MotionSensor = 'WoMotion', - BlindTilt = 'WoBlindTilt', - CeilingLight = 'WoCeilingLight', - CeilingLightPro = 'WoCeilingLightPro', - Leak = 'WoLeakDetector', - Keypad = 'WoKeypad', - RelaySwitch1 = 'WoRelaySwitch1Plus', - RelaySwitch1PM = 'WoRelaySwitch1PM', - Remote = 'WoRemote', - AirPurifier = 'WoAirPurifier', - AirPurifierTable = 'WoAirPurifierTable', - Unknown = 'Unknown', -} - -export enum SwitchBotBLEModelFriendlyName { - Bot = 'Bot', - Hub2 = 'Hub 2', - Hub3 = 'Hub 3', - ColorBulb = 'Color Bulb', - Curtain = 'Curtain', - Curtain3 = 'Curtain 3', - Humidifier = 'Humidifier', - Humidifier2 = 'Humidifier2', - Meter = 'Meter', - Lock = 'Lock', - LockPro = 'Lock Pro', - LockUltra = 'Lock Ultra', - PlugMini = 'Plug Mini', - StripLight = 'Strip Light', - MeterPlus = 'Meter Plus', - MeterPro = 'Meter Pro', - MeterProCO2 = 'Meter Pro CO2', - BatteryCirculatorFan = 'Battery Circulator Fan', - CirculatorFan = 'Circulator Fan', - OutdoorMeter = 'Outdoor Meter', - ContactSensor = 'Contact Sensor', - MotionSensor = 'Motion Sensor', - PresenceSensor = 'Presence Sensor', - BlindTilt = 'Blind Tilt', - CeilingLight = 'Ceiling Light', - CeilingLightPro = 'Ceiling Light Pro', - Leak = 'Water Detector', - Keypad = 'Keypad', - RelaySwitch1 = 'Relay Switch 1', - RelaySwitch1PM = 'Relay Switch 1PM', - Remote = 'Remote', - AirPurifier = 'Air Purifier', - AirPurifierTable = 'Air Purifier Table', - Unknown = 'Unknown', - AirPurifierVOC = 'Air Purifier VOC', - AirPurifierTableVOC = 'Air Purifier Table VOC', - AirPurifierPM2_5 = 'Air Purifier PM2.5', - AirPurifierTablePM2_5 = 'Air Purifier Table PM2.5', -} - -export interface Params { - duration?: number - model?: string - id?: string - quick?: boolean - noble?: Noble -} - -export interface ErrorObject { - code: string - message: string -} - -export interface Chars { - write: Characteristic | null - notify: Characteristic | null - device: Characteristic | null -} - -export interface NobleTypes { - noble: Noble - peripheral: Peripheral -} - -export interface ServiceData { - model: string - [key: string]: unknown -} - -export interface AdvertisementData { - serviceData: Buffer | null - manufacturerData: Buffer | null -} - -export interface Rule { - required?: boolean - min?: number - max?: number - minBytes?: number - maxBytes?: number - pattern?: RegExp - enum?: unknown[] - type?: 'float' | 'integer' | 'boolean' | 'array' | 'object' | 'string' -} - -/** - * Enum for log levels. - */ -export enum LogLevel { - SUCCESS = 'success', - DEBUGSUCCESS = 'debugsuccess', - WARN = 'warn', - DEBUGWARN = 'debugwarn', - ERROR = 'error', - DEBUGERROR = 'debugerror', - DEBUG = 'debug', - INFO = 'info', -} - -/** - * Utility class for comprehensive input validation with improved error messages. - */ -export class ValidationUtils { - /** - * Validates percentage value (0-100). - * @param value - The value to validate - * @param paramName - The parameter name for error reporting - * @throws {RangeError} When value is not within valid range - * @throws {TypeError} When value is not a number - */ - static validatePercentage(value: number, paramName: string = 'value'): void { - if (typeof value !== 'number' || Number.isNaN(value)) { - throw new TypeError(`${paramName} must be a valid number, got: ${value}`) - } - if (value < 0 || value > 100) { - throw new RangeError(`${paramName} must be between 0 and 100 inclusive, got: ${value}`) - } - } - - /** - * Validates RGB color value (0-255). - * @param value - The color value to validate - * @param colorName - The color name for error reporting - * @throws {RangeError} When value is not within valid range - * @throws {TypeError} When value is not a number - */ - static validateRGB(value: number, colorName: string = 'color'): void { - if (typeof value !== 'number' || Number.isNaN(value)) { - throw new TypeError(`${colorName} must be a valid number, got: ${value}`) - } - if (!Number.isInteger(value) || value < 0 || value > 255) { - throw new RangeError(`${colorName} must be an integer between 0 and 255 inclusive, got: ${value}`) - } - } - - /** - * Validates buffer and throws descriptive error. - * @param buffer - The buffer to validate - * @param expectedLength - Optional expected length - * @param paramName - The parameter name for error reporting - * @throws {TypeError} When buffer is not a Buffer - * @throws {RangeError} When buffer length doesn't match expected - */ - static validateBuffer(buffer: any, expectedLength?: number, paramName: string = 'buffer'): asserts buffer is Buffer { - if (!Buffer.isBuffer(buffer)) { - throw new TypeError(`${paramName} must be a Buffer instance, got: ${typeof buffer}`) - } - if (expectedLength !== undefined && buffer.length !== expectedLength) { - throw new RangeError(`${paramName} must have exactly ${expectedLength} bytes, got: ${buffer.length} bytes`) - } - } - - /** - * Validates string input with comprehensive checks. - * @param value - The value to validate - * @param paramName - The parameter name for error reporting - * @param minLength - Minimum required length - * @param maxLength - Optional maximum length - * @throws {TypeError} When value is not a string - * @throws {RangeError} When string length is invalid - */ - static validateString( - value: any, - paramName: string = 'value', - minLength: number = 1, - maxLength?: number, - ): asserts value is string { - if (typeof value !== 'string') { - throw new TypeError(`${paramName} must be a string, got: ${typeof value}`) - } - if (value.length < minLength) { - throw new RangeError(`${paramName} must have at least ${minLength} character(s), got: ${value.length}`) - } - if (maxLength !== undefined && value.length > maxLength) { - throw new RangeError(`${paramName} must have at most ${maxLength} character(s), got: ${value.length}`) - } - } - - /** - * Validates numeric range with enhanced checks. - * @param value - The value to validate - * @param min - Minimum allowed value - * @param max - Maximum allowed value - * @param paramName - The parameter name for error reporting - * @param mustBeInteger - Whether the value must be an integer - * @throws {TypeError} When value is not a number - * @throws {RangeError} When value is outside valid range - */ - static validateRange( - value: number, - min: number, - max: number, - paramName: string = 'value', - mustBeInteger: boolean = false, - ): void { - if (typeof value !== 'number' || Number.isNaN(value)) { - throw new TypeError(`${paramName} must be a valid number, got: ${value}`) - } - if (mustBeInteger && !Number.isInteger(value)) { - throw new TypeError(`${paramName} must be an integer, got: ${value}`) - } - if (value < min || value > max) { - throw new RangeError(`${paramName} must be between ${min} and ${max} inclusive, got: ${value}`) - } - } - - /** - * Validates MAC address format. - * @param address - The MAC address to validate - * @param paramName - The parameter name for error reporting - * @throws {TypeError} When address is not a string - * @throws {Error} When address format is invalid - */ - static validateMacAddress(address: any, paramName: string = 'address'): asserts address is string { - if (typeof address !== 'string') { - throw new TypeError(`${paramName} must be a string`) - } - const macRegex = /^(?:[0-9A-F]{2}[:-]){5}[0-9A-F]{2}$|^[0-9A-F]{12}$/i - if (!macRegex.test(address)) { - throw new Error(`${paramName} must be a valid MAC address format, got: ${address}`) - } - } - - /** - * Validates that a value is one of the allowed enum values. - * @param value - The value to validate - * @param allowedValues - Array of allowed values - * @param paramName - The parameter name for error reporting - * @throws {Error} When value is not in allowed values - */ - static validateEnum(value: any, allowedValues: readonly T[], paramName: string = 'value'): asserts value is T { - if (!allowedValues.includes(value)) { - throw new Error(`${paramName} must be one of: ${allowedValues.join(', ')}, got: ${value}`) - } - } -} - -/** - * Enhanced error handling utilities. - */ -export class ErrorUtils { - /** - * Creates a timeout error with context. - * @param operation - The operation that timed out - * @param timeoutMs - The timeout duration in milliseconds - * @returns A descriptive timeout error - */ - static createTimeoutError(operation: string, timeoutMs: number): Error { - return new Error(`Operation '${operation}' timed out after ${timeoutMs}ms`) - } - - /** - * Creates a connection error with context. - * @param deviceId - The device ID that failed to connect - * @param cause - The underlying cause of the connection failure - * @returns A descriptive connection error - */ - static createConnectionError(deviceId: string, cause?: Error): Error { - const message = `Failed to connect to device ${deviceId}` - return cause ? new Error(`${message}: ${cause.message}`) : new Error(message) - } - - /** - * Creates a command error with context. - * @param command - The command that failed - * @param deviceId - The device ID - * @param cause - The underlying cause - * @returns A descriptive command error - */ - static createCommandError(command: string, deviceId: string, cause?: Error): Error { - const message = `Command '${command}' failed for device ${deviceId}` - return cause ? new Error(`${message}: ${cause.message}`) : new Error(message) - } - - /** - * Wraps an async operation with timeout and enhanced error handling. - * @param operation - The async operation to wrap - * @param timeoutMs - Timeout in milliseconds - * @param operationName - Name of the operation for error messages - * @returns Promise that resolves with the operation result or rejects with timeout - */ - static async withTimeout( - operation: Promise, - timeoutMs: number, - operationName: string, - ): Promise { - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => { - reject(this.createTimeoutError(operationName, timeoutMs)) - }, timeoutMs) - }) - - return Promise.race([operation, timeoutPromise]) - } -} - -/** - * Represents a Switchbot Device. - */ -export class SwitchbotDevice extends EventEmitter { - private noble: Noble - private peripheral: NobleTypes['peripheral'] - private characteristics: Chars | null = null - private deviceId!: string - private deviceAddress!: string - private deviceModel!: SwitchBotBLEModel - private deviceModelName!: SwitchBotBLEModelName - private deviceFriendlyName!: SwitchBotBLEModelFriendlyName - private explicitlyConnected = false - private isConnected = false - private onNotify: (buf: Buffer) => void = () => { } - private onDisconnect: () => Promise = async () => { } - private onConnect: () => Promise = async () => { } - - /** - * Initializes a new instance of the SwitchbotDevice class. - * @param peripheral The peripheral object from noble. - * @param noble The Noble object. - */ - constructor(peripheral: NobleTypes['peripheral'], noble: Noble) { - super() - this.peripheral = peripheral - this.noble = noble - - Advertising.parse(peripheral, this.log.bind(this)).then((ad) => { - this.deviceId = ad?.id ?? '' - this.deviceAddress = ad?.address ?? '' - this.deviceModel = ad?.serviceData.model as SwitchBotBLEModel ?? '' - this.deviceModelName = ad?.serviceData.modelName as SwitchBotBLEModelName ?? '' - this.deviceFriendlyName = ad?.serviceData.modelFriendlyName as SwitchBotBLEModelFriendlyName ?? '' - }) - } - - /** - * Logs a message with the specified log level. - * @param level The severity level of the log (e.g., 'info', 'warn', 'error'). - * @param message The log message to be emitted. - */ - public async log(level: string, message: string): Promise { - this.emit('log', { level, message }) - } - - // Getters - get id(): string { - return this.deviceId - } - - get address(): string { - return this.deviceAddress - } - - get model(): SwitchBotBLEModel { - return this.deviceModel - } - - get modelName(): SwitchBotBLEModelName { - return this.deviceModelName - } - - get friendlyName(): SwitchBotBLEModelFriendlyName { - return this.deviceFriendlyName - } - - get connectionState(): string { - return this.isConnected ? 'connected' : this.peripheral.state - } - - get onConnectHandler(): () => Promise { - return this.onConnect - } - - set onConnectHandler(func: () => Promise) { - if (typeof func !== 'function') { - throw new TypeError('The `onConnectHandler` must be a function that returns a Promise.') - } - this.onConnect = async () => { - await func() - } - } - - get onDisconnectHandler(): () => Promise { - return this.onDisconnect - } - - set onDisconnectHandler(func: () => Promise) { - if (typeof func !== 'function') { - throw new TypeError('The `onDisconnectHandler` must be a function that returns a Promise.') - } - this.onDisconnect = async () => { - await func() - } - } - - /** - * Connects to the device. - * @returns A Promise that resolves when the connection is complete. - */ - async connect(): Promise { - this.explicitlyConnected = true - await this.internalConnect() - } - - /** - * Internal method to handle the connection process. - * @returns A Promise that resolves when the connection is complete. - */ - public async internalConnect(): Promise { - if (this.noble.state !== 'poweredOn') { - throw new Error(`The Bluetooth status is ${this.noble.state}, not poweredOn.`) - } - - const state = this.connectionState - if (state === 'connected') { - return - } - if (state === 'connecting' || state === 'disconnecting') { - throw new Error(`Now ${state}. Wait for a few seconds then try again.`) - } - - this.peripheral.once('connect', async () => { - this.isConnected = true - await this.onConnect() - }) - - this.peripheral.once('disconnect', async () => { - this.isConnected = false - this.characteristics = null - this.peripheral.removeAllListeners() - await this.onDisconnect() - }) - - await this.peripheral.connectAsync() - this.characteristics = await this.getCharacteristics() - await this.subscribeToNotify() - } - - /** - * Retrieves the device characteristics. - * @returns A Promise that resolves with the device characteristics. - */ - public async getCharacteristics(): Promise { - const TIMEOUT_DURATION = 5000 - - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => { - reject(new Error('Failed to discover services and characteristics: TIMEOUT')) - }, TIMEOUT_DURATION) - }) - - try { - const services = await Promise.race([this.discoverServices(), timeoutPromise]) as NobleTypes['peripheral']['services'] - const chars: Chars = { write: null, notify: null, device: null } - - for (const service of services) { - const characteristics = await this.discoverCharacteristics(service) - for (const char of characteristics) { - if (char.uuid === CHAR_UUID_WRITE) { - chars.write = char - } - if (char.uuid === CHAR_UUID_NOTIFY) { - chars.notify = char - } - if (char.uuid === CHAR_UUID_DEVICE) { - chars.device = char - } - } - } - - if (!chars.write || !chars.notify) { - throw new Error('No characteristic was found.') - } - - return chars - } catch (error) { - throw new Error((error as Error).message || 'An error occurred while discovering characteristics.') - } - } - - /** - * Discovers the device services. - * @returns A Promise that resolves with the list of services. - */ - public async discoverServices(): Promise { - try { - const services = await this.peripheral.discoverServicesAsync([]) - const primaryServices = services.filter(s => s.uuid === SERV_UUID_PRIMARY) - - if (primaryServices.length === 0) { - throw new Error('No service was found.') - } - return primaryServices - } catch (e: any) { - throw new Error(`Failed to discover services, Error: ${e.message ?? e}`) - } - } - - /** - * Discovers the characteristics of a service. - * @param service The service to discover characteristics for. - * @returns A Promise that resolves with the list of characteristics. - */ - // Discover characteristics without extra async/await - private discoverCharacteristics(service: Service): Promise { - return service.discoverCharacteristicsAsync([]) - } - - /** - * Subscribes to the notify characteristic. - * @returns A Promise that resolves when the subscription is complete. - */ - private async subscribeToNotify(): Promise { - const char = this.characteristics?.notify - if (!char) { - throw new Error('No notify characteristic was found.') - } - await char.subscribeAsync() - char.on('data', (buf: Buffer) => this.onNotify(buf)) - } - - /** - * Unsubscribes from the notify characteristic. - * @returns A Promise that resolves when the unsubscription is complete. - */ - async unsubscribeFromNotify(): Promise { - const char = this.characteristics?.notify - if (!char) { - return - } - char.removeAllListeners() - await char.unsubscribeAsync() - } - - /** - * Disconnects from the device. - * @returns A Promise that resolves when the disconnection is complete. - */ - async disconnect(): Promise { - this.explicitlyConnected = false - const state = this.peripheral.state - - if (state === 'disconnected') { - return - } - if (state === 'connecting' || state === 'disconnecting') { - throw new Error(`Now ${state}. Wait for a few seconds then try again.`) - } - - await this.unsubscribeFromNotify() - await this.peripheral.disconnectAsync() - } - - /** - * Internal method to handle disconnection if not explicitly initiated. - * @returns A Promise that resolves when the disconnection is complete. - */ - private async internalDisconnect(): Promise { - if (!this.explicitlyConnected) { - await this.disconnect() - this.explicitlyConnected = true - } - } - - /** - * Retrieves the device name. - * @returns A Promise that resolves with the device name. - */ - async getDeviceName(): Promise { - await this.internalConnect() - try { - if (!this.characteristics?.device) { - throw new Error(`Characteristic ${CHAR_UUID_DEVICE} not supported`) - } - const buf = await this.readCharacteristic(this.characteristics.device) - return buf.toString('utf8') - } catch (error: any) { - const deviceContext = `device ${this.deviceId || 'unknown'}` - throw ErrorUtils.createCommandError('getDeviceName', deviceContext, error) - } finally { - await this.internalDisconnect() - } - } - - /** - * Sets the device name. - * @param name The new device name. - * @returns A Promise that resolves when the name is set. - */ - async setDeviceName(name: string): Promise { - ValidationUtils.validateString(name, 'name', 1) - - // Additional validation for device name length - const nameBuffer = Buffer.from(name, 'utf8') - if (nameBuffer.length > 100) { - throw new RangeError('Device name cannot exceed 100 bytes when encoded as UTF-8') - } - - await this.internalConnect() - try { - if (!this.characteristics?.device) { - throw new Error(`Characteristic ${CHAR_UUID_DEVICE} not supported`) - } - await this.writeCharacteristic(this.characteristics.device, nameBuffer) - } catch (error: any) { - const deviceContext = `device ${this.deviceId || 'unknown'}` - throw ErrorUtils.createCommandError('setDeviceName', deviceContext, error) - } finally { - await this.internalDisconnect() - } - } - - /** - * Sends a command to the device and awaits a response. - * @param reqBuf The command buffer. - * @returns A Promise that resolves with the response buffer. - */ - async command(reqBuf: Buffer): Promise { - ValidationUtils.validateBuffer(reqBuf, undefined, 'reqBuf') - - await this.internalConnect() - if (!this.characteristics?.write) { - throw new Error('No write characteristic available for command execution') - } - - try { - await this.writeCharacteristic(this.characteristics.write, reqBuf) - const resBuf = await this.waitForCommandResponse() - return resBuf - } catch (error: any) { - const deviceContext = `device ${this.deviceId || 'unknown'}` - // Use ErrorUtils for enriched error context - throw ErrorUtils.createCommandError('execute command', deviceContext, error) - } finally { - await this.internalDisconnect() - } - } - - /** - * Waits for a response from the device after sending a command. - * @returns A Promise that resolves with the response buffer. - */ - private async waitForCommandResponse(): Promise { - const timeout = READ_TIMEOUT_MSEC - let timer: NodeJS.Timeout | null = null - - const timeoutPromise = new Promise((_, reject) => { - timer = setTimeout(() => reject(new Error('READ_TIMEOUT')), timeout) - }) - - const readPromise = new Promise((resolve) => { - this.onNotify = (buf: Buffer) => { - if (timer) { - clearTimeout(timer) - } - resolve(buf) - } - }) - - return await Promise.race([readPromise, timeoutPromise]) - } - - /** - * Reads data from a characteristic with enhanced timeout and error handling. - * @param char The characteristic to read from. - * @returns A Promise that resolves with the data buffer. - */ - private async readCharacteristic(char: Characteristic): Promise { - try { - return await ErrorUtils.withTimeout( - char.readAsync(), - READ_TIMEOUT_MSEC, - `read characteristic ${char.uuid}`, - ) - } catch (error) { - const deviceContext = `device ${this.deviceId || 'unknown'}` - throw ErrorUtils.createCommandError(`read characteristic ${char.uuid}`, deviceContext, error as Error) - } - } - - /** - * Writes data to a characteristic with enhanced timeout and error handling. - * @param char The characteristic to write to. - * @param buf The data buffer. - * @returns A Promise that resolves when the write is complete. - */ - private async writeCharacteristic(char: Characteristic, buf: Buffer): Promise { - ValidationUtils.validateBuffer(buf, undefined, 'write buffer') - - try { - return await ErrorUtils.withTimeout( - char.writeAsync(buf, false), - WRITE_TIMEOUT_MSEC, - `write to characteristic ${char.uuid}`, - ) - } catch (error) { - const deviceContext = `device ${this.deviceId || 'unknown'}` - throw ErrorUtils.createCommandError(`write to characteristic ${char.uuid}`, deviceContext, error as Error) - } - } -} - -/** - * Represents the advertising data parser for SwitchBot devices. - */ -export class Advertising { - constructor() { } - - /** - * Parses the advertisement data coming from SwitchBot device. - * - * This function processes advertising packets received from SwitchBot devices - * and extracts relevant information based on the device type. - * - * @param {NobleTypes['peripheral']} peripheral - The peripheral device object from noble. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - An object containing parsed data specific to the SwitchBot device type, or `null` if the device is not recognized. - */ - static async parse( - peripheral: NobleTypes['peripheral'], - emitLog: (level: string, message: string) => void, - ): Promise { - const ad = peripheral.advertisement - if (!ad || !ad.serviceData) { - return null - } - - const serviceData = ad.serviceData[0]?.data - const manufacturerData = ad.manufacturerData - - // Service data must exist and contain at least the model byte (1 byte minimum) - // At least one of serviceData or manufacturerData should have sufficient data (3+ bytes) - if (!Advertising.validateBuffer(serviceData, 1)) { - return null - } - - if (!Advertising.validateBuffer(serviceData, 3) && !Advertising.validateBuffer(manufacturerData, 3)) { - return null - } - - const model = serviceData.subarray(0, 1).toString('utf8') - const sd = await Advertising.parseServiceData(model, serviceData, manufacturerData, emitLog) - if (!sd) { - // emitLog('debugerror', `[parseAdvertising.${peripheral.id}.${model}] return null, parsed serviceData empty!`) - return null - } - - const address = Advertising.formatAddress(peripheral) - const data = { - id: peripheral.id, - address, - rssi: peripheral.rssi, - serviceData: { - model, - modelName: sd.modelName || '', - modelFriendlyName: sd.modelFriendlyName || '', - ...sd, - }, - } - - emitLog('debug', `[parseAdvertising.${peripheral.id}.${model}] return ${JSON.stringify(data)}`) - return data - } - - /** - * Validates if the buffer is a valid Buffer object with a minimum length. - * - * @param {any} buffer - The buffer to validate. - * @param {number} minLength - The minimum required length. - * @returns {boolean} - True if the buffer is valid, false otherwise. - */ - private static validateBuffer(buffer: any, minLength: number = 3): boolean { - return buffer && Buffer.isBuffer(buffer) && buffer.length >= minLength - } - - /** - * Parses the service data based on the device model. - * - * @param {string} model - The device model. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - The parsed service data. - */ - public static async parseServiceData( - model: string, - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - switch (model) { - case SwitchBotBLEModel.Bot: - return WoHand.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.Curtain: - case SwitchBotBLEModel.Curtain3: - return WoCurtain.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.Humidifier: - return WoHumi.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.Humidifier2: - return WoHumi2.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.Meter: - return WoSensorTH.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.MeterPlus: - return WoSensorTHPlus.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.MeterPro: - return WoSensorTHPro.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.MeterProCO2: - return WoSensorTHProCO2.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.Hub2: - return WoHub2.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.Hub3: - return WoHub3.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.OutdoorMeter: - return WoIOSensorTH.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.AirPurifier: - return WoAirPurifier.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.AirPurifierTable: - return WoAirPurifierTable.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.MotionSensor: - return WoPresence.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.PresenceSensor: - return WoPresence.parsePresenceSensorServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.ContactSensor: - return WoContact.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.Remote: - return WoRemote.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.ColorBulb: - return WoBulb.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.CeilingLight: - return WoCeilingLight.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.CeilingLightPro: - return WoCeilingLight.parseServiceData_Pro(manufacturerData, emitLog) - case SwitchBotBLEModel.StripLight: - return WoStrip.parseServiceData(serviceData, emitLog) - case SwitchBotBLEModel.PlugMiniUS: - return WoPlugMiniUS.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.PlugMiniJP: - return WoPlugMiniJP.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.PlugMiniEU: - return WoPlugMiniEU.parseServiceData(manufacturerData, emitLog) - case SwitchBotBLEModel.Lock: - return WoSmartLock.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.LockPro: - return WoSmartLockPro.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.LockUltra: - return WoSmartLockUltra.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.BlindTilt: - return WoBlindTilt.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.Leak: - return WoLeak.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.RelaySwitch1: - return WoRelaySwitch1.parseServiceData(serviceData, manufacturerData, emitLog) - case SwitchBotBLEModel.RelaySwitch1PM: - return WoRelaySwitch1PM.parseServiceData(serviceData, manufacturerData, emitLog) - default: - emitLog('debug', `[parseAdvertising.${model}] return null, model "${model}" not available!`) - return null - } - } - - /** - * Formats the address of the peripheral. - * - * @param {NobleTypes['peripheral']} peripheral - The peripheral device object from noble. - * @returns {string} - The formatted address. - */ - private static formatAddress(peripheral: NobleTypes['peripheral']): string { - let address = peripheral.address || '' - if (address === '') { - const str = peripheral.advertisement.manufacturerData?.toString('hex').slice(4, 16) || '' - if (str !== '') { - address = str.match(/.{1,2}/g)?.join(':') || '' - } - } else { - address = address.replace(/-/g, ':') - } - return address - } -} - -/** - * Class representing a WoBlindTilt device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/curtain.md - */ -export class WoBlindTilt extends SwitchbotDevice { - private reverse: boolean = false - - /** - * Parses the service data and manufacturer data for the WoBlindTilt device. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @param {boolean} [reverse] - Whether to reverse the tilt percentage. - * @returns {Promise} - The parsed data object or null if the data is invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - reverse: boolean = false, - ): Promise { - if (![5, 6].includes(manufacturerData.length)) { - emitLog('debugerror', `[parseServiceDataForWoBlindTilt] Buffer length ${manufacturerData.length} !== 5 or 6!`) - return null - } - - const byte2 = serviceData.readUInt8(2) - const byte6 = manufacturerData.subarray(6) - - const tilt = Math.max(Math.min(byte6.readUInt8(2) & 0b01111111, 100), 0) - const inMotion = !!(byte2 & 0b10000000) - const lightLevel = (byte6.readUInt8(1) >> 4) & 0b00001111 - const calibration = !!(byte6.readUInt8(1) & 0b00000001) - const sequenceNumber = byte6.readUInt8(0) - const battery = serviceData.length > 2 ? byte2 & 0b01111111 : 0 - - const data: blindTiltServiceData = { - model: SwitchBotBLEModel.BlindTilt, - modelName: SwitchBotBLEModelName.BlindTilt, - modelFriendlyName: SwitchBotBLEModelFriendlyName.BlindTilt, - calibration, - battery, - inMotion, - tilt: reverse ? 100 - tilt : tilt, - lightLevel, - sequenceNumber, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Opens the blind tilt to the fully open position. - * @returns {Promise} - */ - async open(): Promise { - await this.operateBlindTilt([...BLIND_TILT_COMMANDS.OPEN]) - } - - /** - * Closes the blind tilt up to the nearest endpoint. - * @returns {Promise} - */ - async closeUp(): Promise { - await this.operateBlindTilt([...BLIND_TILT_COMMANDS.CLOSE_UP]) - } - - /** - * Closes the blind tilt down to the nearest endpoint. - * @returns {Promise} - */ - async closeDown(): Promise { - await this.operateBlindTilt([...BLIND_TILT_COMMANDS.CLOSE_DOWN]) - } - - /** - * Closes the blind tilt to the nearest endpoint. - * @returns {Promise} - */ - async close(): Promise { - const position = await this.getPosition() - if (position > 50) { - await this.closeUp() - } else { - await this.closeDown() - } - } - - /** - * Retrieves the current position of the blind tilt. - * @returns {Promise} - The current position of the blind tilt (0-100). - */ - async getPosition(): Promise { - const tiltPosition = await this._getAdvValue('tilt') - return Math.max(0, Math.min(tiltPosition, 100)) - } - - /** - * Retrieves the advertised value for a given key. - * @param {string} key - The key for the advertised value. - * @returns {Promise} - The advertised value. - * @private - */ - private async _getAdvValue(key: string): Promise { - if (key === 'tilt') { - return 50 // Example value - } - throw new Error(`Unknown key: ${key}`) - } - - /** - * Retrieves the basic information of the blind tilt. - * @returns {Promise} - A promise that resolves to an object containing the basic information of the blind tilt. - */ - async getBasicInfo(): Promise { - const data: any = await this.getBasicInfo() - if (!data) { - return null - } - - const tilt = Math.max(Math.min(data[6], 100), 0) - const moving = Boolean(data[5] & 0b00000011) - let opening = false - let closing = false - let up = false - - if (moving) { - opening = Boolean(data[5] & 0b00000010) - closing = !opening && Boolean(data[5] & 0b00000001) - if (opening) { - const flag = Boolean(data[5] & 0b00000001) - up = flag ? this.reverse : !flag - } else { - up = tilt < 50 ? this.reverse : tilt > 50 - } - } - - return { - battery: data[1], - firmware: data[2] / 10.0, - light: Boolean(data[4] & 0b00100000), - fault: Boolean(data[4] & 0b00001000), - solarPanel: Boolean(data[5] & 0b00001000), - calibration: Boolean(data[5] & 0b00000100), - calibrated: Boolean(data[5] & 0b00000100), - inMotion: moving, - motionDirection: { - opening: moving && opening, - closing: moving && closing, - up: moving && up, - down: moving && !up, - }, - tilt: this.reverse ? 100 - tilt : tilt, - timers: data[7], - } - } - - /** - * Pauses the blind tilt operation. - * @returns {Promise} - */ - async pause(): Promise { - await this.operateBlindTilt([...BLIND_TILT_COMMANDS.PAUSE]) - } - - /** - * Runs the blind tilt to the specified position. - * @param {number} percent - The target position percentage (0-100). - * @param {number} mode - The running mode (0 or 1). - * @returns {Promise} - */ - async runToPos(percent: number, mode: number): Promise { - ValidationUtils.validatePercentage(percent, 'percent') - ValidationUtils.validateRange(mode, 0, 1, 'mode', true) - - const adjustedPercent = this.reverse ? 100 - percent : percent - await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, mode, adjustedPercent]) - } - - /** - * Sends a command to operate the blind tilt and handles the response. - * @param {number[]} bytes - The byte array representing the command to be sent to the device. - * @returns {Promise} - * @private - */ - public async operateBlindTilt(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBuf = await this.command(reqBuf) - if (resBuf.length !== 3 || resBuf.readUInt8(0) !== 0x01) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } -} - -/** - * Class representing a WoBulb device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/colorbulb.md - */ -export class WoBulb extends SwitchbotDevice { - /** - * Parses the service data for WoBulb. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - // eslint-disable-next-line unused-imports/no-unused-vars - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 18) { - // emitLog('debugerror', `[parseServiceDataForWoBulb] Buffer length ${serviceData.length} !== 18!`) - return null - } - if (manufacturerData.length !== 13) { - // emitLog('debugerror', `[parseServiceDataForWoBulb] Buffer length ${manufacturerData.length} !== 13!`) - return null - } - - const [ - , byte1, , - byte3, - byte4, - byte5, - byte6, - byte7, - byte8, - byte9, - byte10, - ] = manufacturerData - - const data: colorBulbServiceData = { - model: SwitchBotBLEModel.ColorBulb, - modelName: SwitchBotBLEModelName.ColorBulb, - modelFriendlyName: SwitchBotBLEModelFriendlyName.ColorBulb, - power: !!byte1, - red: byte3, - green: byte4, - blue: byte5, - color_temperature: byte6, - state: !!(byte7 & 0b01111111), - brightness: byte7 & 0b01111111, - delay: (byte8 & 0b10000000) >> 7, - preset: (byte8 & 0b00001000) >> 3, - color_mode: byte8 & 0b00000111, - speed: byte9 & 0b01111111, - loop_index: byte10 & 0b11111110, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Reads the state of the bulb. - * @returns {Promise} - Resolves with a boolean indicating whether the bulb is ON (true) or OFF (false). - */ - async readState(): Promise { - return this.operateBulb([...BULB_COMMANDS.READ_STATE]) - } - - /** - * Sets the state of the bulb. - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - * @private - */ - public async setState(reqByteArray: number[]): Promise { - return this.operateBulb([...BULB_COMMANDS.BASE, ...reqByteArray]) - } - - /** - * Turns on the bulb. - * @returns {Promise} - Resolves with a boolean indicating whether the bulb is ON (true). - */ - async turnOn(): Promise { - return this.setState([...BULB_COMMANDS.TURN_ON]) - } - - /** - * Turns off the bulb. - * @returns {Promise} - Resolves with a boolean indicating whether the bulb is OFF (false). - */ - async turnOff(): Promise { - return this.setState([...BULB_COMMANDS.TURN_OFF]) - } - - /** - * Sets the brightness of the bulb. - * @param {number} brightness - The brightness percentage (0-100). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setBrightness(brightness: number): Promise { - ValidationUtils.validatePercentage(brightness, 'brightness') - return this.setState([...BULB_COMMANDS.SET_BRIGHTNESS, brightness]) - } - - /** - * Sets the color temperature of the bulb. - * @param {number} color_temperature - The color temperature percentage (0-100). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setColorTemperature(color_temperature: number): Promise { - ValidationUtils.validatePercentage(color_temperature, 'color_temperature') - return this.setState([...BULB_COMMANDS.SET_COLOR_TEMP, color_temperature]) - } - - /** - * Sets the RGB color of the bulb. - * @param {number} brightness - The brightness percentage (0-100). - * @param {number} red - The red color value (0-255). - * @param {number} green - The green color value (0-255). - * @param {number} blue - The blue color value (0-255). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setRGB(brightness: number, red: number, green: number, blue: number): Promise { - ValidationUtils.validatePercentage(brightness, 'brightness') - ValidationUtils.validateRGB(red, 'red') - ValidationUtils.validateRGB(green, 'green') - ValidationUtils.validateRGB(blue, 'blue') - return this.setState([...BULB_COMMANDS.SET_RGB, brightness, red, green, blue]) - } - - /** - * Sends a command to the bulb. - * @param {number[]} bytes - The command bytes. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - * @private - */ - private async operateBulb(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBuf = await this.command(reqBuf) - if (resBuf.length === 2) { - const code = resBuf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - throw new Error(`Expecting a 2-byte response, got instead: 0x${resBuf.toString('hex')}`) - } -} - -/** - * Class representing a WoCeilingLight device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/colorbulb.md - */ -export class WoCeilingLight extends SwitchbotDevice { - /** - * Parses the service data for WoCeilingLight. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 13) { - emitLog('debugerror', `[parseServiceDataForWoCeilingLight] Buffer length ${manufacturerData.length} !== 13!`) - return null - } - - const [ - , byte1, , - byte3, - byte4, - byte5, - byte6, - byte7, - byte8, - byte9, - byte10, - ] = manufacturerData - - const data: ceilingLightServiceData = { - model: SwitchBotBLEModel.CeilingLight, - modelName: SwitchBotBLEModelName.CeilingLight, - modelFriendlyName: SwitchBotBLEModelFriendlyName.CeilingLight, - power: !!byte1, - red: byte3, - green: byte4, - blue: byte5, - color_temperature: byte6, - state: !!(byte7 & 0b01111111), - brightness: byte7 & 0b01111111, - delay: (byte8 & 0b10000000) ? 1 : 0, - preset: (byte8 & 0b00001000) ? 1 : 0, - color_mode: byte8 & 0b00000111, - speed: byte9 & 0b01111111, - loop_index: byte10 & 0b11111110, - } - - return data - } - - /** - * Parses the service data for WoCeilingLight Pro. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData_Pro( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 13) { - emitLog('debugerror', `[parseServiceDataForWoCeilingLightPro] Buffer length ${manufacturerData.length} !== 13!`) - return null - } - - const [ - , byte1, , - byte3, - byte4, - byte5, - byte6, - byte7, - byte8, - byte9, - byte10, - ] = manufacturerData - - const data: ceilingLightProServiceData = { - model: SwitchBotBLEModel.CeilingLightPro, - modelName: SwitchBotBLEModelName.CeilingLightPro, - modelFriendlyName: SwitchBotBLEModelFriendlyName.CeilingLightPro, - power: !!byte1, - red: byte3, - green: byte4, - blue: byte5, - color_temperature: byte6, - state: !!(byte7 & 0b01111111), - brightness: byte7 & 0b01111111, - delay: (byte8 & 0b10000000) ? 1 : 0, - preset: (byte8 & 0b00001000) ? 1 : 0, - color_mode: byte8 & 0b00000111, - speed: byte9 & 0b01111111, - loop_index: byte10 & 0b11111110, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Reads the state of the ceiling light. - * @returns {Promise} - Resolves with a boolean indicating whether the light is ON (true) or OFF (false). - */ - async readState(): Promise { - return this.operateCeilingLight([0x57, 0x0F, 0x48, 0x01]) - } - - /** - * Sets the state of the ceiling light. - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setState(reqByteArray: number[]): Promise { - const base = [0x57, 0x0F, 0x47, 0x01] - return this.operateCeilingLight(base.concat(reqByteArray)) - } - - /** - * Turns on the ceiling light. - * @returns {Promise} - Resolves with a boolean indicating whether the light is ON (true). - */ - async turnOn(): Promise { - return this.setState([0x01, 0x01]) - } - - /** - * Turns off the ceiling light. - * @returns {Promise} - Resolves with a boolean indicating whether the light is OFF (false). - */ - async turnOff(): Promise { - return this.setState([0x01, 0x02]) - } - - /** - * Sets the brightness of the ceiling light. - * @param {number} brightness - The brightness percentage (0-100). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setBrightness(brightness: number): Promise { - if (typeof brightness !== 'number' || brightness < 0 || brightness > 100) { - throw new TypeError(`Invalid brightness value: ${brightness}`) - } - return this.setState([0x02, 0x14, brightness]) - } - - /** - * Sets the color temperature of the ceiling light. - * @param {number} color_temperature - The color temperature percentage (0-100). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setColorTemperature(color_temperature: number): Promise { - if (typeof color_temperature !== 'number' || color_temperature < 0 || color_temperature > 100) { - throw new TypeError(`Invalid color temperature value: ${color_temperature}`) - } - return this.setState([0x02, 0x17, color_temperature]) - } - - /** - * Sets the RGB color of the ceiling light. - * @param {number} brightness - The brightness percentage (0-100). - * @param {number} red - The red color value (0-255). - * @param {number} green - The green color value (0-255). - * @param {number} blue - The blue color value (0-255). - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - async setRGB(brightness: number, red: number, green: number, blue: number): Promise { - if ( - typeof brightness !== 'number' || brightness < 0 || brightness > 100 - || typeof red !== 'number' || red < 0 || red > 255 - || typeof green !== 'number' || green < 0 || green > 255 - || typeof blue !== 'number' || blue < 0 || blue > 255 - ) { - throw new TypeError('Invalid RGB or brightness values') - } - return this.setState([0x02, 0x12, brightness, red, green, blue]) - } - - /** - * Sends a command to the ceiling light. - * @param {number[]} bytes - The command bytes. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - */ - public async operateCeilingLight(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBuf = await this.command(reqBuf) - if (resBuf.length === 2) { - const code = resBuf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - throw new Error(`Expecting a 2-byte response, got instead: 0x${resBuf.toString('hex')}`) - } -} - -/** - * Class representing a WoContact device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/contactsensor.md - */ -export class WoContact extends SwitchbotDevice { - /** - * Parses the service data for WoContact. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 9) { - emitLog('debugerror', `[parseServiceDataForWoContact] Buffer length ${serviceData.length} !== 9!`) - return null - } - - const [byte1, byte2, byte3, , , , , , byte8] = serviceData - - const hallState = (byte3 >> 1) & 0b00000011 - const tested = Boolean(byte1 & 0b10000000) - const movement = Boolean(byte1 & 0b01000000) - const battery = byte2 & 0b01111111 - const contact_open = Boolean(byte3 & 0b00000010) - const contact_timeout = Boolean(byte3 & 0b00000100) - const lightLevel = byte3 & 0b00000001 ? 'bright' : 'dark' - const button_count = byte8 & 0b00001111 - const doorState = hallState === 0 ? 'close' : hallState === 1 ? 'open' : 'timeout no closed' - - const data: contactSensorServiceData = { - model: SwitchBotBLEModel.ContactSensor, - modelName: SwitchBotBLEModelName.ContactSensor, - modelFriendlyName: SwitchBotBLEModelFriendlyName.ContactSensor, - movement, - tested, - battery, - contact_open, - contact_timeout, - lightLevel, - button_count, - doorState, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoCurtain device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/curtain.md - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/curtain3.md - */ -export class WoCurtain extends SwitchbotDevice { - /** - * Parses the service data for WoCurtain. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @param {boolean} [reverse] - Whether to reverse the position. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - reverse: boolean = false, - ): Promise { - if (![5, 6].includes(serviceData.length)) { - emitLog('debugerror', `[parseServiceDataForWoCurtain] Buffer length ${serviceData.length} !== 5 or 6!`) - return null - } - - const byte1 = serviceData.readUInt8(1) - const byte2 = serviceData.readUInt8(2) - - let deviceData: Buffer - let batteryData: number | null = null - - if (manufacturerData.length >= 13) { - deviceData = manufacturerData.subarray(8, 11) - batteryData = manufacturerData.readUInt8(12) - } else if (manufacturerData.length >= 11) { - deviceData = manufacturerData.subarray(8, 11) - batteryData = byte2 - } else { - deviceData = serviceData.subarray(3, 6) - batteryData = byte2 - } - - const model = serviceData.subarray(0, 1).toString('utf8') as string ? SwitchBotBLEModel.Curtain : SwitchBotBLEModel.Curtain3 - const calibration = Boolean(byte1 & 0b01000000) - - if (model === SwitchBotBLEModel.Curtain) { - const byte3 = serviceData.readUInt8(3) - const byte4 = serviceData.readUInt8(4) - - const position = byte3 & 0b01111111 - const inMotion = Boolean(byte3 & 0b10000000) - const lightLevel = (byte4 >> 4) & 0b00001111 - const deviceChain = byte4 & 0b00000111 - const battery = byte2 & 0b01111111 - - const data: curtainServiceData = { - model: SwitchBotBLEModel.Curtain, - modelName: SwitchBotBLEModelName.Curtain, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Curtain, - calibration, - battery: battery ?? 0, - inMotion, - position: reverse ? 100 - position : position, - lightLevel, - deviceChain, - } - return data - } else { - const position = Math.max(Math.min(deviceData.readUInt8(0) & 0b01111111, 100), 0) - const inMotion = Boolean(deviceData.readUInt8(0) & 0b10000000) - const lightLevel = (deviceData.readUInt8(1) >> 4) & 0b00001111 - const deviceChain = deviceData.readUInt8(1) & 0b00000111 - const battery = batteryData !== null ? batteryData & 0b01111111 : 0 - - const data: curtain3ServiceData = { - model: SwitchBotBLEModel.Curtain3, - modelName: SwitchBotBLEModelName.Curtain3, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Curtain3, - calibration, - battery, - inMotion, - position: reverse ? 100 - position : position, - lightLevel, - deviceChain, - } - return data - } - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Opens the curtain. - * @param {number} [mode] - Running mode (0x01 = QuietDrift, 0xFF = Default). - * @returns {Promise} - */ - async open(mode: number = 0xFF): Promise { - await this.runToPos(0, mode) - } - - /** - * Closes the curtain. - * @param {number} [mode] - Running mode (0x01 = QuietDrift, 0xFF = Default). - * @returns {Promise} - */ - async close(mode: number = 0xFF): Promise { - await this.runToPos(100, mode) - } - - /** - * Pauses the curtain. - * @returns {Promise} - */ - async pause(): Promise { - await this.operateCurtain([0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF]) - } - - /** - * Runs the curtain to the target position. - * @param {number} percent - The percentage of the target position. - * @param {number} [mode] - Running mode (0x01 = QuietDrift, 0xFF = Default). - * @returns {Promise} - */ - async runToPos(percent: number, mode: number = 0xFF): Promise { - if (typeof percent !== 'number' || typeof mode !== 'number') { - throw new TypeError('Invalid type for percent or mode') - } - percent = Math.max(0, Math.min(100, percent)) - await this.operateCurtain([0x57, 0x0F, 0x45, 0x01, 0x05, mode, percent]) - } - - /** - * Sends a command to the curtain. - * @param {number[]} bytes - The command bytes. - * @returns {Promise} - */ - public async operateCurtain(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || code !== 0x01) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } -} - -/** - * Class representing a WoHand device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/bot.md - */ -export class WoHand extends SwitchbotDevice { - /** - * Parses the service data for WoHand. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (!serviceData || serviceData.length < 3) { - emitLog('debugerror', `[parseServiceData] Service Data Buffer length ${serviceData?.length ?? 0} < 3!`) - return null - } - - const byte1 = serviceData.readUInt8(1) - const byte2 = serviceData.readUInt8(2) - - const data: botServiceData = { - model: SwitchBotBLEModel.Bot, - modelName: SwitchBotBLEModelName.Bot, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Bot, - mode: !!(byte1 & 0b10000000), // Whether the light switch Add-on is used or not. 0 = press, 1 = switch - state: !!(byte1 & 0b01000000), // Whether the switch status is ON or OFF. 0 = on, 1 = off - battery: byte2 & 0b01111111, // % - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Sends a command to the bot. - * @param {Buffer} reqBuf - The command buffer. - * @returns {Promise} - */ - protected async sendCommand(reqBuf: Buffer): Promise { - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || (code !== 0x01 && code !== 0x05)) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } - - /** - * Presses the bot. - * @returns {Promise} - */ - public async press(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x00])) - } - - /** - * Turns on the bot. - * @returns {Promise} - */ - public async turnOn(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x01])) - } - - /** - * Turns off the bot. - * @returns {Promise} - */ - public async turnOff(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x02])) - } - - /** - * Moves the bot down. - * @returns {Promise} - */ - public async down(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x03])) - } - - /** - * Moves the bot up. - * @returns {Promise} - */ - public async up(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x04])) - } -} - -/** - * Class representing a WoHub2 device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoHub2 extends SwitchbotDevice { - /** - * Parses the service data for WoHub2. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 16) { - emitLog('debugerror', `[parseServiceDataForWoHub2] Buffer length ${manufacturerData.length} !== 16!`) - return null - } - - const [byte0, byte1, byte2, , , , , , , , , , byte12] = manufacturerData - - const tempSign = byte1 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte1 & 0b01111111) + (byte0 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - const lightLevel = byte12 & 0b11111 - - const data: hub2ServiceData = { - model: SwitchBotBLEModel.Hub2, - modelName: SwitchBotBLEModelName.Hub2, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Hub2, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte2 & 0b10000000), - humidity: byte2 & 0b01111111, - lightLevel, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoHub3 device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoHub3 extends SwitchbotDevice { - /** - * Parses the service data for WoHub3. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 16) { - emitLog('debugerror', `[parseServiceDataForWoHub3] Buffer length ${manufacturerData.length} !== 16!`) - return null - } - - const [byte0, byte1, byte2, , , , , , , , , , byte12] = manufacturerData - - const tempSign = byte1 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte1 & 0b01111111) + (byte0 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - const lightLevel = byte12 & 0b11111 - - const data: hub3ServiceData = { - model: SwitchBotBLEModel.Hub3, - modelName: SwitchBotBLEModelName.Hub3, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Hub3, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte2 & 0b10000000), - humidity: byte2 & 0b01111111, - lightLevel, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoHumi device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/tree/latest/devicetypes - */ -export class WoHumi extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoHumi. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 8) { - emitLog('debugerror', `[parseServiceDataForWoHumi] Buffer length ${serviceData.length} !== 8!`) - return null - } - - const byte1 = serviceData.readUInt8(1) - const byte4 = serviceData.readUInt8(4) - - const onState = !!(byte1 & 0b10000000) // 1 - on - const autoMode = !!(byte4 & 0b10000000) // 1 - auto - const percentage = byte4 & 0b01111111 // 0-100%, 101/102/103 - Quick gear 1/2/3 - const humidity = autoMode ? 0 : percentage === 101 ? 33 : percentage === 102 ? 66 : percentage === 103 ? 100 : percentage - - const data: humidifierServiceData = { - model: SwitchBotBLEModel.Humidifier, - modelName: SwitchBotBLEModelName.Humidifier, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier, - onState, - autoMode, - percentage: autoMode ? 0 : percentage, - humidity, - } - - return data - } - - /** - * Sends a command to the humidifier. - * @param {Buffer} reqBuf - The command buffer. - * @returns {Promise} - */ - protected async operateHumi(reqBuf: Buffer): Promise { - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || (code !== 0x01 && code !== 0x05)) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } - - /** - * Turns on the humidifier. - * @returns {Promise} - */ - public async turnOn(): Promise { - await this.operateHumi(Buffer.from(TURN_ON_KEY, 'hex')) - } - - /** - * Turns off the humidifier. - * @returns {Promise} - */ - public async turnOff(): Promise { - await this.operateHumi(Buffer.from(TURN_OFF_KEY, 'hex')) - } - - /** - * Increases the humidifier setting. - * @returns {Promise} - */ - public async increase(): Promise { - await this.operateHumi(Buffer.from(INCREASE_KEY, 'hex')) - } - - /** - * Decreases the humidifier setting. - * @returns {Promise} - */ - public async decrease(): Promise { - await this.operateHumi(Buffer.from(DECREASE_KEY, 'hex')) - } - - /** - * Sets the humidifier to auto mode. - * @returns {Promise} - */ - public async setAutoMode(): Promise { - await this.operateHumi(Buffer.from(SET_AUTO_MODE_KEY, 'hex')) - } - - /** - * Sets the humidifier to manual mode. - * @returns {Promise} - */ - public async setManualMode(): Promise { - await this.operateHumi(Buffer.from(SET_MANUAL_MODE_KEY, 'hex')) - } - - /** - * Sets the humidifier level. - * @param {number} level - The level to set (0-100). - * @returns {Promise} - */ - public async percentage(level: number): Promise { - if (level < 0 || level > 100) { - throw new Error('Level must be between 0 and 100') - } - const levelKey = `${HUMIDIFIER_COMMAND_HEADER}0107${level.toString(16).padStart(2, '0')}` - await this.operateHumi(Buffer.from(levelKey, 'hex')) - } -} - -/** - * Class representing a WoHumi device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/tree/latest/devicetypes - */ -export class WoHumi2 extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoHumi. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 8) { - emitLog('debugerror', `[parseServiceDataForWoHumi] Buffer length ${serviceData.length} !== 8!`) - return null - } - - const byte1 = serviceData.readUInt8(1) - const byte4 = serviceData.readUInt8(4) - const byte8 = serviceData.readUInt8(8) - const byte10 = serviceData.readUInt8(10) - const byte11 = serviceData.readUInt8(11) - const byte12 = serviceData.readUInt8(12) - - const onState = !!(byte1 & 0b10000000) // 1 - on - const autoMode = !!(byte4 & 0b10000000) // 1 - auto - const percentage = byte4 & 0b01111111 // 0-100%, 101/102/103 - Quick gear 1/2/3 - const humidity = autoMode ? 0 : percentage === 101 ? 33 : percentage === 102 ? 66 : percentage === 103 ? 100 : percentage - const childLock = !!(byte8 & 0b00100000) - const overHumidifyProtection = !!(byte8 & 0b10000000) - const tankRemoved = !!(byte8 & 0b00000100) - const tiltedAlert = !!(byte8 & 0b00000010) - const filterMissing = !!(byte8 & 0b00000001) - const temperature = (byte10 & 0b01111111) + (byte11 >> 4) / 10 - const filterRunTime = byte12 - const filterAlert = filterRunTime >= 240 - const waterLevel = byte11 & 0b00000011 - - const data: humidifier2ServiceData = { - model: SwitchBotBLEModel.Humidifier2, - modelName: SwitchBotBLEModelName.Humidifier2, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier2, - onState, - autoMode, - percentage: autoMode ? 0 : percentage, - humidity, - childLock, - overHumidifyProtection, - tankRemoved, - tiltedAlert, - filterMissing, - temperature, - filterRunTime, - filterAlert, - waterLevel, - } - - return data - } - - /** - * Sends a command to the humidifier. - * @param {Buffer} reqBuf - The command buffer. - * @returns {Promise} - */ - protected async operateHumi(reqBuf: Buffer): Promise { - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || (code !== 0x01 && code !== 0x05)) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } - - /** - * Turns on the humidifier. - * @returns {Promise} - */ - public async turnOn(): Promise { - await this.operateHumi(Buffer.from(TURN_ON_KEY, 'hex')) - } - - /** - * Turns off the humidifier. - * @returns {Promise} - */ - public async turnOff(): Promise { - await this.operateHumi(Buffer.from(TURN_OFF_KEY, 'hex')) - } - - /** - * Increases the humidifier setting. - * @returns {Promise} - */ - public async increase(): Promise { - await this.operateHumi(Buffer.from(INCREASE_KEY, 'hex')) - } - - /** - * Decreases the humidifier setting. - * @returns {Promise} - */ - public async decrease(): Promise { - await this.operateHumi(Buffer.from(DECREASE_KEY, 'hex')) - } - - /** - * Sets the humidifier to auto mode. - * @returns {Promise} - */ - public async setAutoMode(): Promise { - await this.operateHumi(Buffer.from(SET_AUTO_MODE_KEY, 'hex')) - } - - /** - * Sets the humidifier to manual mode. - * @returns {Promise} - */ - public async setManualMode(): Promise { - await this.operateHumi(Buffer.from(SET_MANUAL_MODE_KEY, 'hex')) - } - - /** - * Sets the humidifier level. - * @param {number} level - The level to set (0-100). - * @returns {Promise} - */ - public async percentage(level: number): Promise { - if (level < 0 || level > 100) { - throw new Error('Level must be between 0 and 100') - } - const levelKey = `${HUMIDIFIER_COMMAND_HEADER}0107${level.toString(16).padStart(2, '0')}` - await this.operateHumi(Buffer.from(levelKey, 'hex')) - } -} - -/** - * Class representing a WoIOSensorTH device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md#outdoor-temperaturehumidity-sensor - */ -export class WoIOSensorTH extends SwitchbotDevice { - /** - * Parses the service data for WoIOSensorTH. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 3) { - emitLog('debugerror', `[parseServiceDataForWoIOSensorTH] Service Data Buffer length ${serviceData.length} !== 3!`) - return null - } - if (manufacturerData.length !== 14) { - emitLog('debugerror', `[parseServiceDataForWoIOSensorTH] Manufacturer Data Buffer length ${manufacturerData.length} !== 14!`) - return null - } - - const [mdByte10, mdByte11, mdByte12] = [ - manufacturerData.readUInt8(10), - manufacturerData.readUInt8(11), - manufacturerData.readUInt8(12), - ] - const sdByte2 = serviceData.readUInt8(2) - - const tempSign = mdByte11 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((mdByte11 & 0b01111111) + (mdByte10 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - const data: outdoorMeterServiceData = { - model: SwitchBotBLEModel.OutdoorMeter, - modelName: SwitchBotBLEModelName.OutdoorMeter, - modelFriendlyName: SwitchBotBLEModelFriendlyName.OutdoorMeter, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(mdByte12 & 0b10000000), - humidity: mdByte12 & 0b01111111, - battery: sdByte2 & 0b01111111, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoKeypad device. - */ -export class WoKeypad extends SwitchbotDevice { - /** - * Parses the service data for WoKeypad. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (!serviceData || serviceData.length < 3) { - emitLog('debugerror', `[parseServiceDataForWoKeypad] Service Data Buffer length ${serviceData?.length ?? 0} < 3!`) - return null - } - - if (!manufacturerData || manufacturerData.length < 2) { - emitLog('debugerror', `[parseServiceDataForWoKeypad] Manufacturer Data Buffer length ${manufacturerData?.length ?? 0} < 2!`) - return null - } - - const modelId = serviceData.readUInt8(0) - - if (modelId !== 0x26) { - // Not a Keypad - emitLog('debugerror', `[parseServiceDataForWoKeypad] Model ID ${modelId} !== 0x26!`) - return null - } - - const eventFlags = serviceData.readUInt8(1) - const keypadEventDetected = !!(eventFlags & 0b00000001) // Bit 0 - const deviceTampered = !!(eventFlags & 0b00000010) // Bit 1 - - const batteryInfo = serviceData.readUInt8(2) - const batteryLevel = batteryInfo & 0b01111111 // Bits 0-6 - const lowBattery = !!(batteryInfo & 0b10000000) // Bit 7 - - // Manufacturer data can be processed here if needed - - const data = { - model: SwitchBotBLEModel.Keypad, - modelName: SwitchBotBLEModelName.Keypad, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Keypad, - event: keypadEventDetected, - tampered: deviceTampered, - battery: batteryLevel, - low_battery: lowBattery, - } - - return data as keypadDetectorServiceData - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoLeak device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md#outdoor-temperaturehumidity-sensor - */ -export class WoLeak extends SwitchbotDevice { - /** - * Parses the service data for WoLeak. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (!serviceData || serviceData.length < 3) { - emitLog('debugerror', `[parseServiceDataForWoLeakDetector] Service Data Buffer length ${serviceData?.length ?? 0} < 3!`) - return null - } - - if (!manufacturerData || manufacturerData.length < 2) { - emitLog('debugerror', `[parseServiceDataForWoLeakDetector] Manufacturer Data Buffer length ${manufacturerData?.length ?? 0} < 2!`) - return null - } - - const waterLeakDetected = manufacturerData.length > 8 && !!(manufacturerData.readUInt8(8) & 0b00000001) // Bit 0 - const deviceTampered = !!(manufacturerData.readUInt8(8) & 0b00000010) // Bit 1 - const batteryLevel = manufacturerData.readUInt8(7) & 0b01111111 // Bits 0-6 - const lowBattery = !!(manufacturerData.readUInt8(7) & 0b10000000) // Bit 7 - - // Manufacturer data can be processed here if needed - - const data = { - model: SwitchBotBLEModel.Leak, - modelName: SwitchBotBLEModelName.Leak, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Leak, - leak: waterLeakDetected, - tampered: deviceTampered, - battery: batteryLevel, - low_battery: lowBattery, - } - - return data as waterLeakDetectorServiceData - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoPlugMini device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/plugmini.md - */ -export class WoPlugMiniJP extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoPlugMini JP. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 14) { - emitLog('debugerror', `[parseServiceDataForWoPlugMiniJP] Buffer length ${manufacturerData.length} should be 14`) - return null - } - - const [byte9, byte10, byte11, byte12, byte13] = [ - manufacturerData.readUInt8(9), - manufacturerData.readUInt8(10), - manufacturerData.readUInt8(11), - manufacturerData.readUInt8(12), - manufacturerData.readUInt8(13), - ] - - const state = byte9 === 0x00 ? 'off' : byte9 === 0x80 ? 'on' : null - const delay = !!(byte10 & 0b00000001) - const timer = !!(byte10 & 0b00000010) - const syncUtcTime = !!(byte10 & 0b00000100) - const wifiRssi = byte11 - const overload = !!(byte12 & 0b10000000) - const currentPower = (((byte12 & 0b01111111) << 8) + byte13) / 10 // in watt - - const data = { - model: SwitchBotBLEModel.PlugMiniJP, - modelName: SwitchBotBLEModelName.PlugMini, - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini, - state: state ?? 'unknown', - delay, - timer, - syncUtcTime, - wifiRssi, - overload, - currentPower, - } - - return data as plugMiniJPServiceData - } - - /** - * Reads the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async readState(): Promise { - return this.operatePlug([0x57, 0x0F, 0x51, 0x01]) - } - - /** - * Sets the state of the plug. - * @private - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async setState(reqByteArray: number[]): Promise { - const base = [0x57, 0x0F, 0x50, 0x01] - return this.operatePlug([...base, ...reqByteArray]) - } - - /** - * Turns on the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOn(): Promise { - return this.setState([0x01, 0x80]) - } - - /** - * Turns off the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOff(): Promise { - return this.setState([0x01, 0x00]) - } - - /** - * Toggles the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async toggle(): Promise { - return this.setState([0x02, 0x80]) - } - - /** - * Operates the plug with the given bytes. - * @param {number[]} bytes - The byte array to send to the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async operatePlug(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBytes = await this.command(reqBuf) - const resBuf = Buffer.from(resBytes) - - if (resBuf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${resBuf.toString('hex')}`) - } - - const code = resBuf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } -} - -/** - * Class representing a WoPlugMini EU device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/plugmini.md - */ -export class WoPlugMiniEU extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoPlugMini EU. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 14) { - emitLog('debugerror', `[parseServiceDataForWoPlugMiniEU] Buffer length ${manufacturerData.length} should be 14`) - return null - } - - const [byte9, byte10, byte11, byte12, byte13] = [ - manufacturerData.readUInt8(9), - manufacturerData.readUInt8(10), - manufacturerData.readUInt8(11), - manufacturerData.readUInt8(12), - manufacturerData.readUInt8(13), - ] - - const state = byte9 === 0x00 ? 'off' : byte9 === 0x80 ? 'on' : null - const delay = !!(byte10 & 0b00000001) - const timer = !!(byte10 & 0b00000010) - const syncUtcTime = !!(byte10 & 0b00000100) - const wifiRssi = byte11 - const overload = !!(byte12 & 0b10000000) - const currentPower = (((byte12 & 0b01111111) << 8) + byte13) / 10 // in watt - - const data = { - model: SwitchBotBLEModel.PlugMiniEU, - modelName: SwitchBotBLEModelName.PlugMini, - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini, - state: state ?? 'unknown', - delay, - timer, - syncUtcTime, - wifiRssi, - overload, - currentPower, - } - - return data as plugMiniEUServiceData - } - - /** - * Reads the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async readState(): Promise { - return this.operatePlug([0x57, 0x0F, 0x51, 0x01]) - } - - /** - * Sets the state of the plug. - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async setState(reqByteArray: number[]): Promise { - const base = [0x57, 0x0F, 0x50, 0x01] - return this.operatePlug([...base, ...reqByteArray]) - } - - /** - * Turns on the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOn(): Promise { - return this.setState([0x01, 0x80]) - } - - /** - * Turns off the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOff(): Promise { - return this.setState([0x01, 0x00]) - } - - /** - * Toggles the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async toggle(): Promise { - return this.setState([0x02, 0x80]) - } - - /** - * Operates the plug with the given bytes. - * @param {number[]} bytes - The byte array to send to the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async operatePlug(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBytes = await this.command(reqBuf) - const resBuf = Buffer.from(resBytes) - - if (resBuf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${resBuf.toString('hex')}`) - } - - const code = resBuf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } -} - -/** - * Class representing a WoPlugMini device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/plugmini.md - */ -export class WoPlugMiniUS extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoPlugMini US. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length !== 14) { - emitLog('debugerror', `[parseServiceDataForWoPlugMini] Buffer length ${manufacturerData.length} should be 14`) - return null - } - - const [byte9, byte10, byte11, byte12, byte13] = [ - manufacturerData.readUInt8(9), - manufacturerData.readUInt8(10), - manufacturerData.readUInt8(11), - manufacturerData.readUInt8(12), - manufacturerData.readUInt8(13), - ] - - const state = byte9 === 0x00 ? 'off' : byte9 === 0x80 ? 'on' : null - const delay = !!(byte10 & 0b00000001) - const timer = !!(byte10 & 0b00000010) - const syncUtcTime = !!(byte10 & 0b00000100) - const wifiRssi = byte11 - const overload = !!(byte12 & 0b10000000) - const currentPower = (((byte12 & 0b01111111) << 8) + byte13) / 10 // in watt - - const data = { - model: SwitchBotBLEModel.PlugMiniUS, - modelName: SwitchBotBLEModelName.PlugMini, - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini, - state: state ?? 'unknown', - delay, - timer, - syncUtcTime, - wifiRssi, - overload, - currentPower, - } - - return data as plugMiniUSServiceData - } - - /** - * Reads the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async readState(): Promise { - return this.operatePlug([0x57, 0x0F, 0x51, 0x01]) - } - - /** - * Sets the state of the plug. - * @private - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - private async setState(reqByteArray: number[]): Promise { - const base = [0x57, 0x0F, 0x50, 0x01] - return this.operatePlug([...base, ...reqByteArray]) - } - - /** - * Turns on the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOn(): Promise { - return this.setState([0x01, 0x80]) - } - - /** - * Turns off the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async turnOff(): Promise { - return this.setState([0x01, 0x00]) - } - - /** - * Toggles the state of the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - async toggle(): Promise { - return this.setState([0x02, 0x80]) - } - - /** - * Operates the plug with the given bytes. - * @param {number[]} bytes - The byte array to send to the plug. - * @returns {Promise} - Resolves with a boolean that tells whether the plug is ON (true) or OFF (false). - */ - public async operatePlug(bytes: number[]): Promise { - const reqBuf = Buffer.from(bytes) - const resBytes = await this.command(reqBuf) - const resBuf = Buffer.from(resBytes) - - if (resBuf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${resBuf.toString('hex')}`) - } - - const code = resBuf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } -} - -const PRESENCE_SENSOR_BATTERY_RANGE_MAP = ['<10%', '10-19%', '20-59%', '>=60%'] as const - -/** - * Class representing a WoPresence device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoPresence extends SwitchbotDevice { - /** - * Parses the service data for WoPresence. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 6) { - emitLog('debugerror', `[parseServiceDataForWoPresence] Buffer length ${serviceData.length} !== 6!`) - return null - } - - const [byte1, byte2, , , , byte5] = serviceData - - const data: motionSensorServiceData = { - model: SwitchBotBLEModel.MotionSensor, - modelName: SwitchBotBLEModelName.MotionSensor, - modelFriendlyName: SwitchBotBLEModelFriendlyName.MotionSensor, - tested: !!(byte1 & 0b10000000), - movement: !!(byte1 & 0b01000000), - battery: byte2 & 0b01111111, - led: (byte5 & 0b00100000) >> 5, - iot: (byte5 & 0b00010000) >> 4, - sense_distance: (byte5 & 0b00001100) >> 2, - lightLevel: (byte5 & 0b00000011) === 1 ? 'dark' : (byte5 & 0b00000011) === 2 ? 'bright' : 'unknown', - is_light: !!(byte5 & 0b00000010), - } - - return data - } - - /** - * Parses the manufacturer data for presence sensors. - * @param {Buffer | null} serviceData - The optional service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parsePresenceSensorServiceData( - serviceData: Buffer | null, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (!manufacturerData || manufacturerData.length < 12) { - emitLog('debugerror', `[parsePresenceSensorServiceData] Manufacturer buffer length ${manufacturerData?.length ?? 0} < 12!`) - return null - } - - const statusByte = manufacturerData[7] - const batteryBits = (statusByte >> 2) & 0b11 - - const data: presenceSensorServiceData = { - model: SwitchBotBLEModel.PresenceSensor, - modelName: SwitchBotBLEModelName.PresenceSensor, - modelFriendlyName: SwitchBotBLEModelFriendlyName.PresenceSensor, - sequenceNumber: manufacturerData[6], - adaptiveState: !!(statusByte & 0b10000000), - motionDetected: !!(statusByte & 0b01000000), - batteryRange: PRESENCE_SENSOR_BATTERY_RANGE_MAP[batteryBits] ?? 'Unknown', - triggerFlag: manufacturerData[10], - ledState: !!(manufacturerData[11] & 0b10000000), - lightLevel: manufacturerData[11] & 0x0F, - } - - if (serviceData && serviceData.length >= 3) { - data.battery = serviceData[2] & 0x7F - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoRelaySwitch1 device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/ - */ -export class WoRelaySwitch1 extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoRelaySwitch1. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length < 8 || manufacturerData.length === null) { - emitLog('debugerror', `[parseServiceDataForWoRelaySwitch1Plus] Buffer length ${serviceData.length} < 8!`) - return null - } - - const data: relaySwitch1ServiceData = { - model: SwitchBotBLEModel.RelaySwitch1, - modelName: SwitchBotBLEModelName.RelaySwitch1, - modelFriendlyName: SwitchBotBLEModelFriendlyName.RelaySwitch1, - mode: true, // for compatibility, useless - state: !!(manufacturerData[7] & 0b10000000), - sequence_number: manufacturerData[6], - } - - return data - } - - /** - * Sends a command to the bot. - * @param {Buffer} reqBuf - The command buffer. - * @returns {Promise} - */ - protected async sendCommand(reqBuf: Buffer): Promise { - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || (code !== 0x01 && code !== 0x05)) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } - - /** - * Turns on the bot. - * @returns {Promise} - */ - public async turnOn(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x01])) - } - - /** - * Turns off the bot. - * @returns {Promise} - */ - public async turnOff(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x02])) - } -} - -/** - * Class representing a WoRelaySwitch1PM device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/ - */ -export class WoRelaySwitch1PM extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Parses the service data for WoRelaySwitch1PM. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length < 8 || manufacturerData.length === 0) { - emitLog('debugerror', `[parseServiceDataForWoRelaySwitch1PM] Buffer length ${serviceData.length} < 8!`) - return null - } - - const data: relaySwitch1PMServiceData = { - model: SwitchBotBLEModel.RelaySwitch1PM, - modelName: SwitchBotBLEModelName.RelaySwitch1PM, - modelFriendlyName: SwitchBotBLEModelFriendlyName.RelaySwitch1PM, - mode: true, // for compatibility, useless - state: !!(manufacturerData[7] & 0b10000000), - sequence_number: manufacturerData[6], - power: ((manufacturerData[10] << 8) + manufacturerData[11]) / 10, - voltage: 0, - current: 0, - } - - return data - } - - /** - * Sends a command to the bot. - * @param {Buffer} reqBuf - The command buffer. - * @returns {Promise} - */ - protected async sendCommand(reqBuf: Buffer): Promise { - const resBuf = await this.command(reqBuf) - const code = resBuf.readUInt8(0) - - if (resBuf.length !== 3 || (code !== 0x01 && code !== 0x05)) { - throw new Error(`The device returned an error: 0x${resBuf.toString('hex')}`) - } - } - - /** - * Turns on the bot. - * @returns {Promise} - */ - public async turnOn(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x01])) - } - - /** - * Turns off the bot. - * @returns {Promise} - */ - public async turnOff(): Promise { - await this.sendCommand(Buffer.from([0x57, 0x01, 0x02])) - } -} - -/** - * Class representing a WoRemote device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/ - */ -export class WoRemote extends SwitchbotDevice { - /** - * Parses the service data for WoRemote. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 9) { - emitLog('debugerror', `[parseServiceDataForWoRemote] Buffer length ${serviceData.length} !== 9!`) - return null - } - - const [byte2] = serviceData - - const battery = byte2 & 0b01111111 - - const data: remoteServiceData = { - model: SwitchBotBLEModel.Remote, - modelName: SwitchBotBLEModelName.Remote, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Remote, - battery, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } -} - -/** - * Class representing a WoSensorTH device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoSensorTH extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 6) { - emitLog('debugerror', `[parseServiceData] Buffer length ${serviceData.length} !== 6!`) - return null - } - - const [byte2, byte3, byte4, byte5] = [ - serviceData.readUInt8(2), - serviceData.readUInt8(3), - serviceData.readUInt8(4), - serviceData.readUInt8(5), - ] - const tempSign = byte4 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - const data = { - model: SwitchBotBLEModel.Meter, - modelName: SwitchBotBLEModelName.Meter, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Meter, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte5 & 0b10000000), - humidity: byte5 & 0b01111111, - battery: byte2 & 0b01111111, - } - return data as meterServiceData - } -} - -/** - * Class representing a WoSensorTH device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoSensorTHPlus extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 6) { - emitLog('debugerror', `[parseServiceData] Buffer length ${serviceData.length} !== 6 or 7!`) - return null - } - - const [byte2, byte3, byte4, byte5] = [ - serviceData.readUInt8(2), - serviceData.readUInt8(3), - serviceData.readUInt8(4), - serviceData.readUInt8(5), - ] - const tempSign = byte4 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - const data = { - model: SwitchBotBLEModel.MeterPlus, - modelName: SwitchBotBLEModelName.MeterPlus, - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPlus, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte5 & 0b10000000), - humidity: byte5 & 0b01111111, - battery: byte2 & 0b01111111, - } - return data as meterPlusServiceData - } -} -/** - * Class representing a WoSensorTH device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoSensorTHPro extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 6) { - emitLog('debugerror', `[parseServiceData] Buffer length ${serviceData.length} !== 6 or 7!`) - return null - } - - const [byte2, byte3, byte4, byte5] = [ - serviceData.readUInt8(2), - serviceData.readUInt8(3), - serviceData.readUInt8(4), - serviceData.readUInt8(5), - ] - const tempSign = byte4 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - const data = { - model: SwitchBotBLEModel.MeterPro, - modelName: SwitchBotBLEModelName.MeterPro, - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPro, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte5 & 0b10000000), - humidity: byte5 & 0b01111111, - battery: byte2 & 0b01111111, - } - return data as meterProServiceData - } -} - -/** - * Class representing a WoSensorTH device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/meter.md - */ -export class WoSensorTHProCO2 extends SwitchbotDevice { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 7 && serviceData.length !== 3) { - emitLog('debugerror', `[parseServiceData] Buffer length ${serviceData.length} !== 3 or 7!`) - return null - } - - if (serviceData.length === 7) { - const [byte2, byte3, byte4, byte5, byte6] = [ - serviceData.readUInt8(2), - serviceData.readUInt8(3), - serviceData.readUInt8(4), - serviceData.readUInt8(5), - manufacturerData.readUInt16BE(6), - ] - const tempSign = byte4 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - return { - model: SwitchBotBLEModel.MeterProCO2, - modelName: SwitchBotBLEModelName.MeterProCO2, - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterProCO2, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(byte5 & 0b10000000), - humidity: byte5 & 0b01111111, - battery: byte2 & 0b01111111, - co2: byte6, - } as meterProCO2ServiceData - } else { - const [mdByte10, mdByte11, mdByte12] = [ - manufacturerData.readUInt8(10), - manufacturerData.readUInt8(11), - manufacturerData.readUInt8(12), - ] - const sdByte2 = serviceData.readUInt8(2) - - const tempSign = mdByte11 & 0b10000000 ? 1 : -1 - const tempC = tempSign * ((mdByte11 & 0b01111111) + (mdByte10 & 0b00001111) / 10) - const tempF = Math.round(((tempC * 9) / 5 + 32) * 10) / 10 - - return { - model: SwitchBotBLEModel.MeterProCO2, - modelName: SwitchBotBLEModelName.MeterProCO2, - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterProCO2, - celsius: tempC, - fahrenheit: tempF, - fahrenheit_mode: !!(mdByte12 & 0b10000000), - humidity: mdByte12 & 0b01111111, - battery: sdByte2 & 0b01111111, - co2: manufacturerData.readUInt16BE(15), - } as meterProCO2ServiceData - } - } -} - -/** - * Class representing a WoSmartLock device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/lock.md - */ -export class WoSmartLock extends SwitchbotDevice { - public iv: Buffer | null = null - public key_id: string = '' - public encryption_key: Buffer | null = null - - static Result = { - ERROR: 0x00, - SUCCESS: 0x01, - SUCCESS_LOW_BATTERY: 0x06, - } - - static async validateResponse(res: Buffer): Promise { - if (res.length >= 3) { - const result = res.readUInt8(0) - if (result === WoSmartLock.Result.SUCCESS || result === WoSmartLock.Result.SUCCESS_LOW_BATTERY) { - return result - } - } - return WoSmartLock.Result.ERROR - } - - static getLockStatus(code: number): string { - const statusMap: { [key: number]: string } = { - 0b0000000: 'LOCKED', - 0b0010000: 'UNLOCKED', - 0b0100000: 'LOCKING', - 0b0110000: 'UNLOCKING', - 0b1000000: 'LOCKING_STOP', - 0b1010000: 'UNLOCKING_STOP', - 0b1100000: 'NOT_FULLY_LOCKED', // Only EU lock type - } - return statusMap[code] || 'UNKNOWN' - } - - /** - * Parses the service data from the SwitchBot Strip Light. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length < 11) { - emitLog('debugerror', `[parseServiceDataForWoSmartLock] Buffer length ${manufacturerData.length} is too short!`) - return null - } - - const byte2 = serviceData.readUInt8(2) - const byte15 = manufacturerData.readUInt8(9) - const byte16 = manufacturerData.readUInt8(10) - - const data: lockServiceData = { - model: SwitchBotBLEModel.Lock, - modelName: SwitchBotBLEModelName.Lock, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Lock, - battery: byte2 & 0b01111111, - calibration: !!(byte15 & 0b10000000), - status: WoSmartLock.getLockStatus(byte15 & 0b01110000), - update_from_secondary_lock: !!(byte15 & 0b00001000), - door_open: !!(byte15 & 0b00000100), - double_lock_mode: !!(byte16 & 0b10000000), - unclosed_alarm: !!(byte16 & 0b00100000), - unlocked_alarm: !!(byte16 & 0b00010000), - auto_lock_paused: !!(byte16 & 0b00000010), - night_latch: !!(manufacturerData.length > 11 && manufacturerData.readUInt8(11) & 0b00000001), - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Initializes the encryption key info for valid lock communication. - * @param {string} keyId - The key ID. - * @param {string} encryptionKey - The encryption key. - */ - async setKey(keyId: string, encryptionKey: string): Promise { - this.iv = null - this.key_id = keyId - this.encryption_key = Buffer.from(encryptionKey, 'hex') - } - - /** - * Unlocks the Smart Lock. - * @returns {Promise} - The result of the unlock operation. - */ - async unlock(): Promise { - const resBuf = await this.operateLock(WoSmartLockCommands.UNLOCK) - return resBuf ? WoSmartLock.validateResponse(resBuf) : WoSmartLock.Result.ERROR - } - - /** - * Unlocks the Smart Lock without unlatching the door. - * @returns {Promise} - The result of the unlock operation. - */ - async unlockNoUnlatch(): Promise { - const resBuf = await this.operateLock(WoSmartLockCommands.UNLOCK_NO_UNLATCH) - return resBuf ? WoSmartLock.validateResponse(resBuf) : WoSmartLock.Result.ERROR - } - - /** - * Locks the Smart Lock. - * @returns {Promise} - The result of the lock operation. - */ - async lock(): Promise { - const resBuf = await this.operateLock(WoSmartLockCommands.LOCK) - return resBuf ? WoSmartLock.validateResponse(resBuf) : WoSmartLock.Result.ERROR - } - - /** - * Gets general state info from the Smart Lock. - * @returns {Promise} - The state object or null if an error occurred. - */ - async info(): Promise { - const resBuf = await this.operateLock(WoSmartLockCommands.LOCK_INFO) - if (resBuf) { - return { - calibration: Boolean(resBuf[1] & 0b10000000), - status: WoSmartLock.getLockStatus((resBuf[1] & 0b01110000)), - door_open: Boolean(resBuf[1] & 0b00000100), - unclosed_alarm: Boolean(resBuf[2] & 0b00100000), - unlocked_alarm: Boolean(resBuf[2] & 0b00010000), - } - } - return null - } - - /** - * Encrypts a string using AES-128-CTR. - * @param {string} str - The string to encrypt. - * @returns {Promise} - The encrypted string in hex format. - */ - async encrypt(str: string): Promise { - const cipher = Crypto.createCipheriv('aes-128-ctr', this.encryption_key!, this.iv) - return Buffer.concat([cipher.update(str, 'hex'), cipher.final()]).toString('hex') - } - - /** - * Decrypts a buffer using AES-128-CTR. - * @param {Buffer} data - The data to decrypt. - * @returns {Promise} - The decrypted data. - */ - async decrypt(data: Buffer): Promise { - const decipher = Crypto.createDecipheriv('aes-128-ctr', this.encryption_key!, this.iv) - return Buffer.concat([decipher.update(data), decipher.final()]) - } - - /** - * Retrieves the IV from the device. - * @returns {Promise} - The IV buffer. - */ - async getIv(): Promise { - if (!this.iv) { - const res = await this.operateLock(WoSmartLockCommands.GET_CKIV + this.key_id, false) - if (res) { - this.iv = res.subarray(4) - } else { - throw new Error('Failed to retrieve IV from the device.') - } - } - return this.iv - } - - /** - * Sends an encrypted command to the device. - * @param {string} key - The command key. - * @returns {Promise} - The response buffer. - */ - async encryptedCommand(key: string): Promise { - const iv = await this.getIv() - const req = Buffer.from( - key.substring(0, 2) + this.key_id + Buffer.from(iv.subarray(0, 2)).toString('hex') + await this.encrypt(key.substring(2)), - 'hex', - ) - - const bytes = await this.command(req) - const buf = Buffer.from(bytes as Uint8Array) - const code = WoSmartLock.validateResponse(buf) - - if (await code !== WoSmartLock.Result.ERROR) { - return Buffer.concat([buf.subarray(0, 1), await this.decrypt(buf.subarray(4))]) - } else { - throw new Error(`The device returned an error: 0x${buf.toString('hex')}`) - } - } - - /** - * Operates the lock with the given command. - * @param {string} key - The command key. - * @param {boolean} [encrypt] - Whether to encrypt the command. - * @returns {Promise} - The response buffer. - */ - async operateLock(key: string, encrypt: boolean = true): Promise { - if (encrypt) { - return this.encryptedCommand(key) - } - const req = Buffer.from(`${key.substring(0, 2)}000000${key.substring(2)}`, 'hex') - const bytes = await this.command(req) - const buf = Buffer.from(bytes as Uint8Array) - const code = WoSmartLock.validateResponse(buf) - - if (await code === WoSmartLock.Result.ERROR) { - throw new Error(`The device returned an error: 0x${buf.toString('hex')}`) - } - return buf - } -} - -/** - * Class representing a WoSmartLockPro device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/lock.md - */ -export class WoSmartLockPro extends SwitchbotDevice { - public iv: Buffer | null = null - public key_id: string = '' - public encryption_key: Buffer | null = null - - static Result = { - ERROR: 0x00, - SUCCESS: 0x01, - SUCCESS_LOW_BATTERY: 0x06, - } - - static async validateResponse(res: Buffer) { - if (res.length >= 3) { - const result = res.readUInt8(0) - if (result === WoSmartLockPro.Result.SUCCESS || result === WoSmartLockPro.Result.SUCCESS_LOW_BATTERY) { - return result - } - } - return WoSmartLockPro.Result.ERROR - } - - static getLockStatus(code: number) { - const statusMap: { [key: number]: string } = { - 0b0000000: 'LOCKED', - 0b0010000: 'UNLOCKED', - 0b0100000: 'LOCKING', - 0b0110000: 'UNLOCKING', - 0b1000000: 'LOCKING_STOP', - 0b1010000: 'UNLOCKING_STOP', - 0b01100000: 'NOT_FULLY_LOCKED', // Only EU lock type - } - return statusMap[code] || 'UNKNOWN' - } - - /** - * Parses the service data from the SwitchBot Strip Light. - * @param {Buffer} serviceData - The service data buffer. - * @param {Buffer} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (manufacturerData.length < 11) { - emitLog('debugerror', `[parseServiceDataForWoSmartLockPro] Buffer length ${manufacturerData.length} is too short!`) - return null - } - - const byte2 = serviceData.readUInt8(2) - const byte7 = manufacturerData.readUInt8(7) - const byte8 = manufacturerData.readUInt8(8) - const byte9 = manufacturerData.readUInt8(9) - const byte11 = manufacturerData.readUInt8(11) - - const data: lockProServiceData = { - model: SwitchBotBLEModel.LockPro, - modelName: SwitchBotBLEModelName.LockPro, - modelFriendlyName: SwitchBotBLEModelFriendlyName.LockPro, - battery: byte2 & 0b01111111, - calibration: !!(byte7 & 0b10000000), - status: WoSmartLockPro.getLockStatus((byte7 & 0b00111000) >> 3), - door_open: !!(byte8 & 0b01100000), - update_from_secondary_lock: false, - double_lock_mode: false, - unclosed_alarm: !!(byte11 & 0b10000000), - unlocked_alarm: !!(byte11 & 0b01000000), - auto_lock_paused: !!(byte8 & 0b100000), - night_latch: !!(byte9 & 0b00000001), - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Initializes the encryption key info for valid lock communication. - * @param {string} keyId - The key ID. - * @param {string} encryptionKey - The encryption key. - */ - async setKey(keyId: string, encryptionKey: string) { - this.iv = null - this.key_id = keyId - this.encryption_key = Buffer.from(encryptionKey, 'hex') - } - - /** - * Unlocks the Smart Lock. - * @returns {Promise} - The result of the unlock operation. - */ - async unlock(): Promise { - const resBuf = await this.operateLockPro(WoSmartLockProCommands.UNLOCK) - return resBuf ? WoSmartLockPro.validateResponse(resBuf) : WoSmartLockPro.Result.ERROR - } - - /** - * Unlocks the Smart Lock without unlatching the door. - * @returns {Promise} - The result of the unlock operation. - */ - async unlockNoUnlatch(): Promise { - const resBuf = await this.operateLockPro(WoSmartLockProCommands.UNLOCK_NO_UNLATCH) - return resBuf ? WoSmartLockPro.validateResponse(resBuf) : WoSmartLockPro.Result.ERROR - } - - /** - * Locks the Smart Lock. - * @returns {Promise} - The result of the lock operation. - */ - async lock(): Promise { - const resBuf = await this.operateLockPro(WoSmartLockProCommands.LOCK) - return resBuf ? WoSmartLockPro.validateResponse(resBuf) : WoSmartLockPro.Result.ERROR - } - - /** - * Gets general state info from the Smart Lock. - * @returns {Promise} - The state object or null if an error occurred. - */ - async info(): Promise { - const resBuf = await this.operateLockPro(WoSmartLockProCommands.LOCK_INFO) - if (resBuf) { - return { - calibration: Boolean(resBuf[0] & 0b10000000), - status: WoSmartLockPro.getLockStatus((resBuf[0] & 0b01110000) >> 4), - door_open: Boolean(resBuf[0] & 0b00000100), - unclosed_alarm: Boolean(resBuf[1] & 0b00100000), - unlocked_alarm: Boolean(resBuf[1] & 0b00010000), - } - } - return null - } - - /** - * Encrypts a string using AES-128-CTR. - * @param {string} str - The string to encrypt. - * @returns {Promise} - The encrypted string in hex format. - */ - async encrypt(str: string): Promise { - const cipher = Crypto.createCipheriv('aes-128-ctr', this.encryption_key!, this.iv) - return Buffer.concat([cipher.update(str, 'hex'), cipher.final()]).toString('hex') - } - - /** - * Decrypts a buffer using AES-128-CTR. - * @param {Buffer} data - The data to decrypt. - * @returns {Promise} - The decrypted data. - */ - async decrypt(data: Buffer): Promise { - const decipher = Crypto.createDecipheriv('aes-128-ctr', this.encryption_key!, this.iv) - return Buffer.concat([decipher.update(data), decipher.final()]) - } - - /** - * Retrieves the IV from the device. - * @returns {Promise} - The IV buffer. - */ - async getIv(): Promise { - if (!this.iv) { - const res = await this.operateLockPro(WoSmartLockProCommands.GET_CKIV + this.key_id, false) - if (res) { - this.iv = res.subarray(4) - } else { - throw new Error('Failed to retrieve IV from the device.') - } - } - return this.iv - } - - /** - * Sends an encrypted command to the device. - * @param {string} key - The command key. - * @returns {Promise} - The response buffer. - */ - async encryptedCommand(key: string): Promise { - const iv = await this.getIv() - const req = Buffer.from( - key.substring(0, 2) + this.key_id + Buffer.from(iv.subarray(0, 2)).toString('hex') + await this.encrypt(key.substring(2)), - 'hex', - ) - - const bytes = await this.command(req) - const buf = Buffer.from(bytes as Uint8Array) - const code = WoSmartLockPro.validateResponse(buf) - - if (await code !== WoSmartLockPro.Result.ERROR) { - return Buffer.concat([buf.subarray(0, 1), await this.decrypt(buf.subarray(4))]) - } else { - throw new Error(`The device returned an error: 0x${buf.toString('hex')}`) - } - } - - /** - * Operates the lock with the given command. - * @param {string} key - The command key. - * @param {boolean} [encrypt] - Whether to encrypt the command. - * @returns {Promise} - The response buffer. - */ - async operateLockPro(key: string, encrypt: boolean = true): Promise { - if (encrypt) { - return this.encryptedCommand(key) - } - const req = Buffer.from(`${key.substring(0, 2)}000000${key.substring(2)}`, 'hex') - const bytes = await this.command(req) - const buf = Buffer.from(bytes as Uint8Array) - const code = WoSmartLockPro.validateResponse(buf) - - if (await code === WoSmartLockPro.Result.ERROR) { - throw new Error(`The device returned an error: 0x${buf.toString('hex')}`) - } - return buf - } -} - -/** - * Class representing a WoSmartLockUltra device. - * Reuses the LockPro parsing and encrypted command behavior but reports a distinct model. - */ -export class WoSmartLockUltra extends WoSmartLockPro { - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - static async parseServiceData( - serviceData: Buffer, - manufacturerData: Buffer, - emitLog: (level: string, message: string) => void, - ) { - const data = await WoSmartLockPro.parseServiceData(serviceData, manufacturerData, emitLog) - if (!data) return null - const out = data as any - out.model = SwitchBotBLEModel.LockUltra - out.modelName = SwitchBotBLEModelName.LockUltra - out.modelFriendlyName = SwitchBotBLEModelFriendlyName.LockUltra - return out - } -} - -/** - * Class representing a WoStrip device. - * @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/ledstriplight.md - */ -export class WoStrip extends SwitchbotDevice { - /** - * Parses the service data from the SwitchBot Strip Light. - * @param {Buffer} serviceData - The service data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {Promise} - Parsed service data or null if invalid. - */ - static async parseServiceData( - serviceData: Buffer, - emitLog: (level: string, message: string) => void, - ): Promise { - if (serviceData.length !== 18) { - emitLog('debugerror', `[parseServiceDataForWoStrip] Buffer length ${serviceData.length} !== 18!`) - return null - } - - const [byte3, byte4, byte5, byte7, byte8, byte9, byte10] = [ - serviceData.readUInt8(3), - serviceData.readUInt8(4), - serviceData.readUInt8(5), - serviceData.readUInt8(7), - serviceData.readUInt8(8), - serviceData.readUInt8(9), - serviceData.readUInt8(10), - ] - - const data: stripLightServiceData = { - model: SwitchBotBLEModel.StripLight, - modelName: SwitchBotBLEModelName.StripLight, - modelFriendlyName: SwitchBotBLEModelFriendlyName.StripLight, - power: !!(byte7 & 0b10000000), - state: !!(byte7 & 0b10000000), - brightness: byte7 & 0b01111111, - red: byte3, - green: byte4, - blue: byte5, - color_temperature: 0, // Add a default value or extract from serviceData if available - delay: byte8 & 0b10000000, - preset: byte8 & 0b00001000, - color_mode: byte8 & 0b00000111, - speed: byte9 & 0b01111111, - loop_index: byte10 & 0b11111110, - } - - return data - } - - constructor(peripheral: NobleTypes['peripheral'], noble: NobleTypes['noble']) { - super(peripheral, noble) - } - - /** - * Reads the state of the strip light. - * @returns {Promise} - Resolves with true if the strip light is ON, false otherwise. - */ - async readState(): Promise { - return this.operateStripLight([0x57, 0x0F, 0x4A, 0x01]) - } - - /** - * Sets the state of the strip light. - * @public - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with true if the operation was successful. - */ - public async setState(reqByteArray: number[]): Promise { - const base = [0x57, 0x0F, 0x49, 0x01] - return this.operateStripLight([...base, ...reqByteArray]) - } - - /** - * Turns the strip light on. - * @returns {Promise} - Resolves with true if the strip light is ON. - */ - async turnOn(): Promise { - return this.setState([0x01, 0x01]) - } - - /** - * Turns the strip light off. - * @returns {Promise} - Resolves with true if the strip light is OFF. - */ - async turnOff(): Promise { - return this.setState([0x01, 0x02]) - } - - /** - * Sets the brightness of the strip light. - * @param {number} brightness - The brightness percentage (0-100). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setBrightness(brightness: number): Promise { - if (typeof brightness !== 'number' || brightness < 0 || brightness > 100) { - throw new TypeError(`Invalid brightness value: ${brightness}`) - } - return this.setState([0x02, 0x14, brightness]) - } - - /** - * Sets the RGB values of the strip light. - * @param {number} brightness - The brightness percentage (0-100). - * @param {number} red - The red value (0-255). - * @param {number} green - The green value (0-255). - * @param {number} blue - The blue value (0-255). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setRGB(brightness: number, red: number, green: number, blue: number): Promise { - if (![brightness, red, green, blue].every(val => typeof val === 'number')) { - throw new TypeError('Invalid RGB or brightness value') - } - - brightness = Math.max(0, Math.min(100, brightness)) - red = Math.max(0, Math.min(255, red)) - green = Math.max(0, Math.min(255, green)) - blue = Math.max(0, Math.min(255, blue)) - - return this.setState([0x02, 0x12, brightness, red, green, blue]) - } - - /** - * Operates the strip light with the given byte array. - * @public - * @param {number[]} bytes - The byte array to send. - * @returns {Promise} - Resolves with true if the operation was successful. - */ - public async operateStripLight(bytes: number[]): Promise { - const req_buf = Buffer.from(bytes) - const res_buf = await this.command(req_buf) - - if (res_buf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${res_buf.toString('hex')}`) - } - - const code = res_buf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${res_buf.toString('hex')}`) - } - } -} - -/** - * Class representing a SwitchBot Air Purifier device. - * @extends SwitchbotDevice - */ -export class WoAirPurifier extends SwitchbotDevice { - /** - * Parses service data for air purifier devices. - * @param {Buffer | null} serviceData - The service data buffer. - * @param {Buffer | null} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {airPurifierServiceData | null} - The parsed service data or null. - */ - static parseServiceData(serviceData: Buffer | null, manufacturerData: Buffer | null, emitLog?: (level: string, message: string) => void): airPurifierServiceData | null { - if (!manufacturerData || manufacturerData.length < 14) { - return null - } - - const deviceData = manufacturerData.subarray(6) - - if (deviceData.length < 8) { - return null - } - - const sequenceNumber = deviceData[0] - const isOn = Boolean(deviceData[1] & 0b10000000) - const mode = deviceData[1] & 0b00000111 - const isAqiValid = Boolean(deviceData[2] & 0b00000100) - const childLock = Boolean(deviceData[2] & 0b00000010) - const speed = deviceData[3] & 0b01111111 - const aqiLevelRaw = (deviceData[4] & 0b00000110) >> 1 - const workTime = (deviceData[5] << 8) | deviceData[6] - const errCode = deviceData[7] - - // Map AQI level to string using the defined constant - const aqiLevelValues = [ - AIR_QUALITY_LEVELS.EXCELLENT, - AIR_QUALITY_LEVELS.GOOD, - AIR_QUALITY_LEVELS.FAIR, - AIR_QUALITY_LEVELS.POOR, - ] - const aqiLevel = aqiLevelValues[aqiLevelRaw] || 'unknown' - - // Determine mode based on mode value and speed - let modeString: string | null = null - if (mode === 1) { - if (speed >= 0 && speed <= 33) { - modeString = AIR_PURIFIER_MODES.LEVEL_1 - } else if (speed >= 34 && speed <= 66) { - modeString = AIR_PURIFIER_MODES.LEVEL_2 - } else { - modeString = AIR_PURIFIER_MODES.LEVEL_3 - } - } else if (mode > 1 && mode <= 4) { - const modeMap = [null, null, 'auto', 'sleep', 'manual'] - modeString = modeMap[mode + 2] || null - } - - if (emitLog) { - emitLog('debug', `Air Purifier Service Data: isOn=${isOn}, mode=${modeString}, speed=${speed}, AQI=${aqiLevel}`) - } - - return { - model: SwitchBotBLEModel.AirPurifier, - modelName: SwitchBotBLEModelName.AirPurifier, - modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifier, - isOn, - mode: modeString, - isAqiValid, - child_lock: childLock, - speed, - aqi_level: aqiLevel, - filter_element_working_time: workTime, - err_code: errCode, - sequence_number: sequenceNumber, - } - } - - /** - * Sets the state of the air purifier. - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - * @private - */ - public async setState(reqByteArray: number[]): Promise { - return this.operateAirPurifier(reqByteArray) - } - - /** - * Turns the air purifier on. - * @returns {Promise} - Resolves with true if the air purifier is turned on. - */ - async turnOn(): Promise { - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]) - } - - /** - * Turns the air purifier off. - * @returns {Promise} - Resolves with true if the air purifier is turned off. - */ - async turnOff(): Promise { - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_OFF]) - } - - /** - * Sets the speed of the air purifier. - * @param {number} speed - The speed value (0-100). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setSpeed(speed: number): Promise { - if (typeof speed !== 'number' || speed < 0 || speed > 100) { - throw new TypeError(`Invalid speed value: ${speed}`) - } - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_SPEED, speed]) - } - - /** - * Sets the mode of the air purifier. - * @param {number} mode - The mode value (1-4). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setMode(mode: number): Promise { - if (typeof mode !== 'number' || mode < 1 || mode > 4) { - throw new TypeError(`Invalid mode value: ${mode}`) - } - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, mode]) - } - - /** - * Operates the air purifier with the given byte array. - * @public - * @param {number[]} bytes - The byte array to send. - * @returns {Promise} - Resolves with true if the operation was successful. - */ - public async operateAirPurifier(bytes: number[]): Promise { - const req_buf = Buffer.from(bytes) - const res_buf = await this.command(req_buf) - - if (res_buf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${res_buf.toString('hex')}`) - } - - const code = res_buf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${res_buf.toString('hex')}`) - } - } -} - -/** - * Class representing a SwitchBot Air Purifier Table device. - * @extends SwitchbotDevice - */ -export class WoAirPurifierTable extends SwitchbotDevice { - /** - * Parses service data for air purifier table devices. - * @param {Buffer | null} serviceData - The service data buffer. - * @param {Buffer | null} manufacturerData - The manufacturer data buffer. - * @param {Function} emitLog - The function to emit log messages. - * @returns {airPurifierTableServiceData | null} - The parsed service data or null. - */ - static parseServiceData(serviceData: Buffer | null, manufacturerData: Buffer | null, emitLog?: (level: string, message: string) => void): airPurifierTableServiceData | null { - if (!manufacturerData || manufacturerData.length < 14) { - return null - } - - const deviceData = manufacturerData.subarray(6) - - if (deviceData.length < 8) { - return null - } - - const sequenceNumber = deviceData[0] - const isOn = Boolean(deviceData[1] & 0b10000000) - const mode = deviceData[1] & 0b00000111 - const isAqiValid = Boolean(deviceData[2] & 0b00000100) - const childLock = Boolean(deviceData[2] & 0b00000010) - const speed = deviceData[3] & 0b01111111 - const aqiLevelRaw = (deviceData[4] & 0b00000110) >> 1 - const workTime = (deviceData[5] << 8) | deviceData[6] - const errCode = deviceData[7] - - // Map AQI level to string using the defined constant - const aqiLevelValues = [ - AIR_QUALITY_LEVELS.EXCELLENT, - AIR_QUALITY_LEVELS.GOOD, - AIR_QUALITY_LEVELS.FAIR, - AIR_QUALITY_LEVELS.POOR, - ] - const aqiLevel = aqiLevelValues[aqiLevelRaw] || 'unknown' - - // Determine mode based on mode value and speed - let modeString: string | null = null - if (mode === 1) { - if (speed >= 0 && speed <= 33) { - modeString = AIR_PURIFIER_MODES.LEVEL_1 - } else if (speed >= 34 && speed <= 66) { - modeString = AIR_PURIFIER_MODES.LEVEL_2 - } else { - modeString = AIR_PURIFIER_MODES.LEVEL_3 - } - } else if (mode > 1 && mode <= 4) { - const modeMap = [null, null, 'auto', 'sleep', 'manual'] - modeString = modeMap[mode + 2] || null - } - - if (emitLog) { - emitLog('debug', `Air Purifier Table Service Data: isOn=${isOn}, mode=${modeString}, speed=${speed}, AQI=${aqiLevel}`) - } - - return { - model: SwitchBotBLEModel.AirPurifierTable, - modelName: SwitchBotBLEModelName.AirPurifierTable, - modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifierTable, - isOn, - mode: modeString, - isAqiValid, - child_lock: childLock, - speed, - aqi_level: aqiLevel, - filter_element_working_time: workTime, - err_code: errCode, - sequence_number: sequenceNumber, - } - } - - /** - * Sets the state of the air purifier table. - * @param {number[]} reqByteArray - The request byte array. - * @returns {Promise} - Resolves with a boolean indicating whether the operation was successful. - * @private - */ - public async setState(reqByteArray: number[]): Promise { - return this.operateAirPurifierTable(reqByteArray) - } - - /** - * Turns the air purifier table on. - * @returns {Promise} - Resolves with true if the air purifier table is turned on. - */ - async turnOn(): Promise { - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]) - } - - /** - * Turns the air purifier table off. - * @returns {Promise} - Resolves with true if the air purifier table is turned off. - */ - async turnOff(): Promise { - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_OFF]) - } - - /** - * Sets the speed of the air purifier table. - * @param {number} speed - The speed value (0-100). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setSpeed(speed: number): Promise { - if (typeof speed !== 'number' || speed < 0 || speed > 100) { - throw new TypeError(`Invalid speed value: ${speed}`) - } - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_SPEED, speed]) - } - - /** - * Sets the mode of the air purifier table. - * @param {number} mode - The mode value (1-4). - * @returns {Promise} - Resolves with true if the operation was successful. - */ - async setMode(mode: number): Promise { - if (typeof mode !== 'number' || mode < 1 || mode > 4) { - throw new TypeError(`Invalid mode value: ${mode}`) - } - return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, mode]) - } - - /** - * Operates the air purifier table with the given byte array. - * @public - * @param {number[]} bytes - The byte array to send. - * @returns {Promise} - Resolves with true if the operation was successful. - */ - public async operateAirPurifierTable(bytes: number[]): Promise { - const req_buf = Buffer.from(bytes) - const res_buf = await this.command(req_buf) - - if (res_buf.length !== 2) { - throw new Error(`Expecting a 2-byte response, got instead: 0x${res_buf.toString('hex')}`) - } - - const code = res_buf.readUInt8(1) - if (code === 0x00 || code === 0x80) { - return code === 0x80 - } else { - throw new Error(`The device returned an error: 0x${res_buf.toString('hex')}`) - } - } -} diff --git a/src/devices/base.ts b/src/devices/base.ts new file mode 100644 index 00000000..c371038e --- /dev/null +++ b/src/devices/base.ts @@ -0,0 +1,1017 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/base.ts: SwitchBot v4.0.0 - Base Device Class + */ + +import type { OpenAPIClient } from '../api.js' +import type { BLEConnection } from '../ble.js' +import type { CommandResult, ConnectionType, DeviceInfo, DeviceStatus } from '../types/index.js' +import type { CircuitBreakerConfig, FallbackHandler, FallbackHandlerOptions, RetryConfig } from '../utils/index.js' // ms + +import { Buffer } from 'node:buffer' +import { EventEmitter } from 'node:events' + +import { APINotAvailableError, BLENotAvailableError } from '../errors.js' +import { DEVICE_COMMANDS } from '../settings.js' +import { + CircuitBreaker, + + CircuitBreakerState, + ConnectionTracker, + + FallbackHandlerManager, + + Logger, + + RetryExecutor, +} from '../utils/index.js' +// Passive polling interval (24 hours) +export const PASSIVE_POLL_INTERVAL = 60 * 60 * 24 * 1000 + +/** + * Base class for all SwitchBot devices + * + * ## BLE-first, API-fallback Logic + * + * This class provides a centralized, robust hybrid connection strategy for all SwitchBot devices: + * + * - **BLE-first, API-fallback**: By default, status and command methods attempt BLE first (if available), then fall back to OpenAPI if BLE fails or is unavailable. This is controlled by `preferredConnection` and `enableFallback`. + * - **Centralized Fallback**: The `getStatusWithFallback()` and `sendCommand()` methods implement this logic. Device subclasses should call these methods and provide normalization/mapping as needed. + * - **Connection Intelligence**: Tracks connection health and performance, automatically preferring the most reliable connection if enabled. + * - **Circuit Breaker & Retry**: Both BLE and API commands are protected by circuit breaker and retry logic to handle transient failures gracefully. + * + * ### Usage in Subclasses + * + * - For status: Call `await this.getStatusWithFallback(normalizeBLE, normalizeAPI)` in your `getStatus()` implementation. + * - For commands: Use `await this.sendCommand(bleCommand, apiCommand, apiParameter)` to automatically select the best connection and handle fallback. + * - For custom logic: You may override or extend these methods, but should preserve the fallback and error-handling patterns for consistency. + * + * ### Example (in a device subclass) + * + * ```typescript + * async getStatus(): Promise { + * return this.getStatusWithFallback( + * bleData => ({ ... }), // normalize BLE data + * apiData => ({ ... }), // normalize API data + * ) + * } + * + * async turnOn(): Promise { + * const result = await this.sendCommand([0x57, 0x01, 0x01], 'turnOn') + * return result.success + * } + * ``` + * + * ### Configuration + * + * - `preferredConnection`: 'ble' | 'api' (default: 'ble') + * - `enableFallback`: boolean (default: true) + * - `enableConnectionIntelligence`: boolean (default: true) + * - `enableCircuitBreaker`: boolean (default: true) + * - `enableRetry`: boolean (default: true) + * + * ### See Also + * - `getStatusWithFallback()` + * - `sendCommand()` + * - `hasBLE()`, `hasAPI()` + * - `setPreferredConnection()`, `setFallbackEnabled()` + * + * This pattern ensures all device classes benefit from robust, testable, and consistent connection logic. + */ +export abstract class SwitchBotDevice extends EventEmitter { + protected logger: Logger + protected bleConnection?: BLEConnection + protected apiClient?: OpenAPIClient + protected enableFallback: boolean + protected preferredConnection: ConnectionType + + // Advanced features + protected connectionTracker: ConnectionTracker + protected circuitBreakerBLE: CircuitBreaker + protected circuitBreakerAPI: CircuitBreaker + protected fallbackHandlerManager: FallbackHandlerManager + protected retryExecutor: RetryExecutor + protected enableConnectionIntelligence: boolean + protected enableCircuitBreaker: boolean + protected enableRetry: boolean + private bleOperationQueue: Promise = Promise.resolve() + + // Passive polling + private lastPolledAt?: number + + private defineCompatibilityProperties(): void { + const properties: Array<'id' | 'name' | 'deviceType' | 'mac' | 'activeConnection'> = ['id', 'name', 'deviceType', 'mac', 'activeConnection'] + + for (const property of properties) { + Object.defineProperty(this, property, { + enumerable: true, + configurable: true, + get: () => { + const value = this.info[property] + + if ((property === 'id' || property === 'mac') && typeof value === 'string' && value.length === 0) { + return undefined + } + + return value + }, + }) + } + } + + constructor( + protected info: DeviceInfo, + options: { + bleConnection?: BLEConnection + apiClient?: OpenAPIClient + enableFallback?: boolean + preferredConnection?: ConnectionType + enableConnectionIntelligence?: boolean + enableCircuitBreaker?: boolean + enableRetry?: boolean + retryConfig?: RetryConfig + circuitBreakerConfig?: CircuitBreakerConfig + logLevel?: number + } = {}, + ) { + super() + + this.defineCompatibilityProperties() + + this.logger = new Logger(`${info.deviceType}:${info.id}`, options.logLevel) + this.bleConnection = options.bleConnection + this.apiClient = options.apiClient + this.enableFallback = options.enableFallback ?? true + this.preferredConnection = options.preferredConnection ?? 'ble' + + // Initialize advanced features + this.enableConnectionIntelligence = options.enableConnectionIntelligence ?? true + this.enableCircuitBreaker = options.enableCircuitBreaker ?? true + this.enableRetry = options.enableRetry ?? true + + // Create connection tracker for this device + this.connectionTracker = new ConnectionTracker(info.id, options.logLevel) + + // Create circuit breakers for each connection type + this.circuitBreakerBLE = new CircuitBreaker(`${info.deviceType}:${info.id}:BLE`, options.circuitBreakerConfig, options.logLevel) + this.circuitBreakerAPI = new CircuitBreaker(`${info.deviceType}:${info.id}:API`, options.circuitBreakerConfig, options.logLevel) + + // Create retry executor + this.retryExecutor = new RetryExecutor(options.retryConfig, options.logLevel) + + // Create fallback handler manager + this.fallbackHandlerManager = new FallbackHandlerManager(options.logLevel) + } + + /** + * Send multiple commands in sequence (all must succeed) + * Used for Curtain 3, bulbs, strips, and other multi-step devices + */ + async sendCommandSequence(commands: Array<() => Promise>): Promise { + try { + for (const command of commands) { + const success = await command() + if (!success) { + this.logger.warn('Command in sequence failed, stopping execution') + return false + } + // Small delay between commands for device processing + await new Promise(resolve => setTimeout(resolve, 100)) + } + return true + } catch (error) { + this.logger.error('Command sequence failed', error) + return false + } + } + + /** + * Send multiple commands (returns true if any succeed) + * Used for fallback operations with complex patterns + */ + async sendMultipleCommands(commands: Array<() => Promise>): Promise { + let anySucceeded = false + for (const command of commands) { + try { + const success = await command() + if (success) { + anySucceeded = true + } + // Small delay between commands + await new Promise(resolve => setTimeout(resolve, 100)) + } catch (error) { + this.logger.debug('Command in multi-command attempt failed', error) + // Continue trying other commands + } + } + return anySucceeded + } + + /** + * Returns true if device should be polled (passive polling interval elapsed) + */ + pollNeeded(interval: number = PASSIVE_POLL_INTERVAL): boolean { + if (!this.lastPolledAt) { + return true + } + return Date.now() - this.lastPolledAt > interval + } + + /** + * Poll device status if needed (passive polling) + */ + async pollIfNeeded(interval: number = PASSIVE_POLL_INTERVAL): Promise { + if (this.pollNeeded(interval)) { + const status = await this.getStatus() + this.lastPolledAt = Date.now() + return status + } + return undefined + } + + /** + * Get device information + */ + getInfo(): DeviceInfo { + return { ...this.info } + } + + /** + * Get device ID + */ + getId(): string { + return this.info.id + } + + /** + * Get device ID (property accessor for convenience) + */ + get id(): string | undefined { + return this.info.id.length > 0 ? this.info.id : undefined + } + + /** + * Get device name + */ + getName(): string { + return this.info.name + } + + /** + * Get device name (property accessor for convenience) + */ + get name(): string { + return this.info.name + } + + /** + * Get device type + */ + getDeviceType(): string { + return this.info.deviceType + } + + /** + * Get device type (property accessor for convenience) + */ + get deviceType(): string { + return this.info.deviceType + } + + /** + * Get MAC address (if available) + */ + getMAC(): string | undefined { + return this.info.mac && this.info.mac.length > 0 ? this.info.mac : undefined + } + + /** + * Get MAC address (property accessor for convenience) + */ + get mac(): string | undefined { + return this.info.mac && this.info.mac.length > 0 ? this.info.mac : undefined + } + + /** + * Get active connection type + */ + getActiveConnection(): ConnectionType | undefined { + return this.info.activeConnection + } + + /** + * Get active connection type (property accessor for convenience) + */ + get activeConnection(): ConnectionType | undefined { + return this.info.activeConnection + } + + /** + * Check if BLE is available for this device + */ + hasBLE(): boolean { + return this.info.connectionTypes.includes('ble') && !!this.bleConnection && !!this.info.mac + } + + /** + * Check if API is available for this device + */ + hasAPI(): boolean { + return this.info.connectionTypes.includes('api') && !!this.apiClient && this.info.cloudServiceEnabled !== false + } + + /** + * Get device status (abstract - implemented by subclasses) + */ + /** + * Get device status with BLE-first/API-fallback logic (centralized) + * Subclasses should call this and map/normalize fields as needed. + */ + protected async getStatusWithFallback( + normalizeBLE?: (bleData: any) => TStatus, + normalizeAPI?: (apiData: any) => TStatus, + ): Promise { + // Determine connection order + const preferBLE = this.preferredConnection === 'ble' + const tryBLE = () => this.getBLEStatus().then(normalizeBLE ?? (d => d as TStatus)) + const tryAPI = () => this.getAPIStatus().then(normalizeAPI ?? (d => d as TStatus)) + + // BLE-first + if (preferBLE && this.hasBLE()) { + try { + return await tryBLE() + } catch (err) { + this.logger?.warn?.('BLE getStatus failed, falling back to API', err) + } + if (this.enableFallback && this.hasAPI()) { + return await tryAPI() + } + } + // API-first + if (!preferBLE && this.hasAPI()) { + try { + return await tryAPI() + } catch (err) { + this.logger?.warn?.('API getStatus failed, falling back to BLE', err) + } + if (this.enableFallback && this.hasBLE()) { + return await tryBLE() + } + } + throw new Error('No connection method available for getStatus') + } + + abstract getStatus(): Promise + + /** + * Send a command via BLE with circuit breaker and retry logic + */ + protected async sendBLECommand( + command: readonly number[] | number[] | Buffer, + ): Promise { + if (!this.hasBLE()) { + return { + success: false, + connectionType: 'ble', + error: 'BLE not available for this device', + } + } + + // Check circuit breaker + if (this.enableCircuitBreaker && !this.circuitBreakerBLE.canExecute()) { + const state = this.circuitBreakerBLE.getState() + if (state === CircuitBreakerState.OPEN) { + return { + success: false, + connectionType: 'ble', + error: 'BLE circuit breaker is OPEN (too many failures)', + } + } + } + + const executeCommand = async () => { + this.logger.debug('Sending BLE command', command) + const buffer = Buffer.isBuffer(command) ? command : Buffer.from(command) + + const startTime = Date.now() + const mac = this.info.mac ?? `id:${this.info.bleId}` + + let response: Buffer | undefined + if (this.info.encryptionKey && this.info.encryptionIV && this.bleConnection?.setEncryption) { + this.bleConnection.setEncryption( + mac, + this.info.encryptionKey, + this.info.encryptionIV, + this.info.encryptionMode ?? 'auto', + ) + } + + if (this.bleConnection?.sendCommand) { + response = await this.bleConnection.sendCommand(mac, buffer, { + expectResponse: true, + validateResponse: true, + responseTimeoutMs: 1200, + }) + } else { + await this.bleConnection!.write(mac, buffer) + } + const latencyMs = Date.now() - startTime + + // Record success + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordSuccess('ble', latencyMs) + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerBLE.recordSuccess() + } + + this.info.activeConnection = 'ble' + this.emit('command', { type: 'ble', success: true }) + + return { + success: true, + connectionType: 'ble' as const, + data: response, + } + } + + try { + return await this.runWithBLELock(async () => { + if (this.enableRetry) { + this.circuitBreakerBLE.markHalfOpenAttempt() + return await this.retryExecutor.executeOrThrow(executeCommand, `BLE command for ${this.info.id}`) + } else { + if (this.enableCircuitBreaker) { + this.circuitBreakerBLE.markHalfOpenAttempt() + } + return await executeCommand() + } + }) + } catch (error) { + // Record failure + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordFailure('ble') + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerBLE.recordFailure() + } + + this.logger.error('BLE command failed', error) + this.emit('error', { type: 'ble', error }) + + return { + success: false, + connectionType: 'ble', + error: (error as Error).message, + } + } + } + + /** + * Send a command via OpenAPI with circuit breaker and retry logic + */ + protected async sendAPICommand(command: string, parameter?: any): Promise { + if (!this.hasAPI()) { + return { + success: false, + connectionType: 'api', + error: 'API not available for this device', + } + } + + // Check circuit breaker + if (this.enableCircuitBreaker && !this.circuitBreakerAPI.canExecute()) { + const state = this.circuitBreakerAPI.getState() + if (state === CircuitBreakerState.OPEN) { + return { + success: false, + connectionType: 'api', + error: 'API circuit breaker is OPEN (too many failures)', + } + } + } + + const executeCommand = async () => { + this.logger.debug('Sending API command', { command, parameter }) + + const startTime = Date.now() + const response = await this.apiClient!.sendCommand(this.info.id, command, parameter) + const latencyMs = Date.now() - startTime + + // Record success + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordSuccess('api', latencyMs) + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerAPI.recordSuccess() + } + + this.info.activeConnection = 'api' + this.emit('command', { type: 'api', success: true }) + + return { + success: true, + connectionType: 'api' as const, + data: response, + } + } + + try { + if (this.enableRetry) { + this.circuitBreakerAPI.markHalfOpenAttempt() + return await this.retryExecutor.executeOrThrow(executeCommand, `API command for ${this.info.id}`) + } else { + if (this.enableCircuitBreaker) { + this.circuitBreakerAPI.markHalfOpenAttempt() + } + return await executeCommand() + } + } catch (error) { + // Record failure + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordFailure('api') + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerAPI.recordFailure() + } + + this.logger.error('API command failed', error) + this.emit('error', { type: 'api', error }) + + return { + success: false, + connectionType: 'api', + error: (error as Error).message, + } + } + } + + /** + * Get best connection type based on intelligence tracking + */ + private getBestConnection(): ConnectionType { + if (!this.enableConnectionIntelligence) { + return this.preferredConnection + } + + const availableTypes: ConnectionType[] = [] + if (this.hasBLE()) { + availableTypes.push('ble') + } + if (this.hasAPI()) { + availableTypes.push('api') + } + + if (availableTypes.length === 0) { + return this.preferredConnection + } + + // Get best connection based on statistics + const best = this.connectionTracker.getBestConnection(availableTypes) + + if (best) { + return best + } + + return availableTypes.length > 0 ? availableTypes[0] : this.preferredConnection + } + + /** + * Send a command with automatic BLE/API fallback, circuit breaker, and retry logic + */ + protected async sendCommand( + bleCommand: readonly number[] | number[] | Buffer, + apiCommand: string, + apiParameter?: any, + ): Promise { + // Determine connection strategy + let primaryConnection = this.preferredConnection + let secondaryConnection: ConnectionType | undefined + + if (this.enableConnectionIntelligence) { + primaryConnection = this.getBestConnection() + + if (this.preferredConnection === 'ble' && primaryConnection === 'api' && this.hasBLE()) { + secondaryConnection = 'ble' + } else if (this.preferredConnection === 'api' && primaryConnection === 'ble' && this.hasAPI()) { + secondaryConnection = 'api' + } + } else { + // Fallback based on preferred connection + if (this.preferredConnection === 'ble' && this.hasBLE()) { + primaryConnection = 'ble' + if (this.enableFallback && this.hasAPI()) { + secondaryConnection = 'api' + } + } else if (this.preferredConnection === 'api' && this.hasAPI()) { + primaryConnection = 'api' + if (this.enableFallback && this.hasBLE()) { + secondaryConnection = 'ble' + } + } else if (this.hasBLE()) { + primaryConnection = 'ble' + if (this.enableFallback && this.hasAPI()) { + secondaryConnection = 'api' + } + } else { + primaryConnection = 'api' + secondaryConnection = undefined + } + } + + // Try primary connection + let result: CommandResult + let fallbackUsed = false + + if (primaryConnection === 'ble') { + result = await this.sendBLECommand(bleCommand) + } else { + result = await this.sendAPICommand(apiCommand, apiParameter) + } + + // Try fallback if primary failed and fallback is enabled + if (!result.success && this.enableFallback && secondaryConnection) { + fallbackUsed = true + + this.logger.warn(`${primaryConnection} failed, attempting fallback to ${secondaryConnection}`) + + // Emit fallback event + const fallbackEvent = { + deviceId: this.info.id, + primaryConnection, + fallbackConnection: secondaryConnection, + reason: result.error || 'Connection failed', + timestamp: new Date(), + totalTimeMs: 0, + } + + await this.fallbackHandlerManager.emit(fallbackEvent) + + if (secondaryConnection === 'ble') { + result = await this.sendBLECommand(bleCommand) + } else { + result = await this.sendAPICommand(apiCommand, apiParameter) + } + } + + if (fallbackUsed) { + result.usedFallback = true + } + + return result + } + + /** + * Get device status via BLE + */ + protected async getBLEStatus(): Promise { + if (!this.hasBLE()) { + throw new BLENotAvailableError('BLE not available for this device') + } + + try { + this.logger.debug('Reading BLE status') + const startTime = Date.now() + const data = await this.bleConnection!.read(this.info.mac ?? `id:${this.info.bleId}`) + const latencyMs = Date.now() - startTime + + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordSuccess('ble', latencyMs) + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerBLE.recordSuccess() + } + + this.info.activeConnection = 'ble' + return this.normalizeBLEStatusData(data) + } catch (error) { + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordFailure('ble') + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerBLE.recordFailure() + } + + this.logger.error('Failed to read BLE status', error) + throw error + } + } + + protected normalizeBLEStatusData(data: any): Record { + if (data && typeof data === 'object' && !Buffer.isBuffer(data)) { + return data as Record + } + + return (this.info.bleServiceData ?? {}) as Record + } + + private async runWithBLELock(fn: () => Promise): Promise { + const previous = this.bleOperationQueue + let release: () => void = () => {} + this.bleOperationQueue = new Promise((resolve) => { + release = resolve + }) + + await previous + try { + return await fn() + } finally { + release() + } + } + + /** + * Get device status via OpenAPI + */ + protected async getAPIStatus(): Promise { + if (!this.hasAPI()) { + throw new APINotAvailableError('API not available for this device') + } + + try { + this.logger.debug('Reading API status') + const startTime = Date.now() + const data = await this.apiClient!.getStatus(this.info.id) + const latencyMs = Date.now() - startTime + + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordSuccess('api', latencyMs) + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerAPI.recordSuccess() + } + + this.info.activeConnection = 'api' + return data + } catch (error) { + if (this.enableConnectionIntelligence) { + this.connectionTracker.recordFailure('api') + } + + if (this.enableCircuitBreaker) { + this.circuitBreakerAPI.recordFailure() + } + + this.logger.error('Failed to read API status', error) + throw error + } + } + + /** + * Get basic device info (universal settings retrieval) + * Returns: battery, firmware, device-specific settings, etc. + * Command: 0x57 0x02 (BLE), 'getBasicInfo' (API) + * + * Example usage: + * const info = await device.getBasicInfo(); + * console.log(info); + * + * Returns a CommandResult object with device info fields. + */ + async getBasicInfo(): Promise { + // Prefer BLE if available + if (this.hasBLE()) { + return this.sendBLECommand(DEVICE_COMMANDS.RELAY.GET_BASIC_INFO) + } + // Fallback to API if available + if (this.hasAPI()) { + return this.sendAPICommand('getBasicInfo') + } + throw new Error('No available connection for getBasicInfo') + } + + /** + * Universal mode setting command + * BLE: 0x57 0x03 [modeByte] + * API: 'setMode' (if available) + * @param mode - Mode value (number or string, per-device enum recommended) + * + * Example usage: + * await device.setMode('auto') + * await device.setMode(1) + * + * Returns a CommandResult object indicating success and mode info. + */ + async setMode(mode: number | string): Promise { + // TODO: Extend with per-device mode enums/types as needed + if (this.hasBLE()) { + // BLE expects [0x57, 0x03, modeByte] + const modeByte = typeof mode === 'number' ? mode : Number.parseInt(mode as string, 10) + return this.sendBLECommand([0x57, 0x03, modeByte]) + } + if (this.hasAPI()) { + // API expects 'setMode' command, parameter may be device-specific + return this.sendAPICommand('setMode', { mode }) + } + throw new Error('No available connection for setMode') + } + + /** + * Update device information + */ + updateInfo(newInfo: Partial): void { + this.info = { ...this.info, ...newInfo } + this.emit('info-updated', this.info) + } + + /** + * Set preferred connection type + */ + setPreferredConnection(type: ConnectionType): void { + this.preferredConnection = type + this.logger.info(`Preferred connection set to ${type}`) + } + + /** + * Enable or disable fallback + */ + setFallbackEnabled(enabled: boolean): void { + this.enableFallback = enabled + this.logger.info(`Fallback ${enabled ? 'enabled' : 'disabled'}`) + } + + /** + * Enable or disable connection intelligence + */ + setConnectionIntelligenceEnabled(enabled: boolean): void { + this.enableConnectionIntelligence = enabled + this.logger.info(`Connection intelligence ${enabled ? 'enabled' : 'disabled'}`) + } + + /** + * Enable or disable circuit breaker + */ + setCircuitBreakerEnabled(enabled: boolean): void { + this.enableCircuitBreaker = enabled + this.logger.info(`Circuit breaker ${enabled ? 'enabled' : 'disabled'}`) + } + + /** + * Enable or disable retry logic + */ + setRetryEnabled(enabled: boolean): void { + this.enableRetry = enabled + this.logger.info(`Retry logic ${enabled ? 'enabled' : 'disabled'}`) + } + + /** + * Get connection tracker for this device + */ + getConnectionTracker(): ConnectionTracker { + return this.connectionTracker + } + + /** + * Get circuit breaker for BLE + */ + getCircuitBreakerBLE() { + return this.circuitBreakerBLE + } + + /** + * Get circuit breaker for API + */ + getCircuitBreakerAPI() { + return this.circuitBreakerAPI + } + + /** + * Register a custom fallback handler + */ + registerFallbackHandler( + handler: FallbackHandler, + options?: FallbackHandlerOptions, + ): string { + return this.fallbackHandlerManager.register(handler, options) + } + + /** + * Unregister a fallback handler + */ + unregisterFallbackHandler(id: string): boolean { + return this.fallbackHandlerManager.unregister(id) + } + + /** + * Get fallback handler manager + */ + getFallbackHandlerManager(): FallbackHandlerManager { + return this.fallbackHandlerManager + } +} + +/** + * Device Manager for managing multiple devices + */ +export class DeviceManager extends EventEmitter { + private devices: Map = new Map() + private logger: Logger + + constructor(logLevel?: number) { + super() + this.logger = new Logger('DeviceManager', logLevel) + } + + /** + * Add a device to the manager + */ + add(device: SwitchBotDevice): void { + const id = device.getId() + + if (this.devices.has(id)) { + this.logger.warn(`Device ${id} already exists, replacing`) + } + + this.devices.set(id, device) + this.emit('device-added', device) + this.logger.info(`Added device: ${device.getName()} (${id})`) + } + + /** + * Remove a device from the manager + */ + remove(deviceId: string): boolean { + const device = this.devices.get(deviceId) + + if (device) { + this.devices.delete(deviceId) + this.emit('device-removed', device) + this.logger.info(`Removed device: ${deviceId}`) + return true + } + + return false + } + + /** + * Get a device by ID + */ + get(deviceId: string): SwitchBotDevice | undefined { + return this.devices.get(deviceId) + } + + /** + * Get all devices + */ + list(): SwitchBotDevice[] { + return [...this.devices.values()] + } + + /** + * Get devices filtered by type + */ + getByType(deviceType: string): SwitchBotDevice[] { + return this.list().filter(device => device.getDeviceType() === deviceType) + } + + /** + * Get device by MAC address + */ + getByMAC(mac: string): SwitchBotDevice | undefined { + return this.list().find(device => device.getMAC() === mac) + } + + /** + * Check if device exists + */ + has(deviceId: string): boolean { + return this.devices.has(deviceId) + } + + /** + * Get device count + */ + count(): number { + return this.devices.size + } + + /** + * Clear all devices + */ + clear(): void { + this.devices.clear() + this.emit('devices-cleared') + this.logger.info('All devices cleared') + } + + /** + * Get all device IDs + */ + getIds(): string[] { + return [...this.devices.keys()] + } + + /** + * Get devices as an object keyed by ID + */ + toObject(): Record { + return Object.fromEntries(this.devices.entries()) + } +} diff --git a/src/devices/device-override-state-during-connection.ts b/src/devices/device-override-state-during-connection.ts new file mode 100644 index 00000000..d6913b89 --- /dev/null +++ b/src/devices/device-override-state-during-connection.ts @@ -0,0 +1,74 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/device-override-state-during-connection.ts: SwitchBot v4.0.0 - Device Override State During Connection Base Class + */ + +import type { OpenAPIClient } from '../api.js' +import type { BLEConnection } from '../ble.js' +import type { ConnectionType, DeviceInfo } from '../types/index.js' +import type { CircuitBreakerConfig, RetryConfig } from '../utils/index.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Base class for devices that should ignore advertisement state while connected. + * Prevents stale BLE advertisement data from overriding active connection state. + */ +export abstract class DeviceOverrideStateDuringConnection extends SwitchBotDevice { + constructor( + info: DeviceInfo, + options: { + bleConnection?: BLEConnection + apiClient?: OpenAPIClient + enableFallback?: boolean + preferredConnection?: ConnectionType + enableConnectionIntelligence?: boolean + enableCircuitBreaker?: boolean + enableRetry?: boolean + retryConfig?: RetryConfig + circuitBreakerConfig?: CircuitBreakerConfig + logLevel?: number + } = {}, + ) { + super(info, options) + } + + override updateInfo(newInfo: Partial): void { + if (!this.isBLEConnected()) { + super.updateInfo(newInfo) + return + } + + const filtered: Partial = { ...newInfo } + delete filtered.bleServiceData + delete filtered.battery + delete filtered.rssi + + super.updateInfo(filtered) + } + + protected override normalizeBLEStatusData(data: any): Record { + if (data && typeof data === 'object') { + return super.normalizeBLEStatusData(data) + } + + if (this.isBLEConnected()) { + return {} + } + + return super.normalizeBLEStatusData(data) + } + + protected isBLEConnected(): boolean { + if (!this.bleConnection?.isConnected) { + return false + } + + const macOrBleId = this.info.mac ?? (this.info.bleId ? `id:${this.info.bleId}` : undefined) + if (!macOrBleId) { + return false + } + + return this.bleConnection.isConnected(macOrBleId) + } +} diff --git a/src/devices/index.ts b/src/devices/index.ts new file mode 100644 index 00000000..07de17c4 --- /dev/null +++ b/src/devices/index.ts @@ -0,0 +1,70 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/index.ts: SwitchBot v4.0.0 - Device Exports + */ + +export { DeviceManager, SwitchBotDevice } from './base.js' +export { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js' +export { SequenceDevice } from './sequence-device.js' +export { WoAIHub } from './wo-ai-hub.js' +export { WoAirPurifierPM25 } from './wo-air-purifier-pm25.js' +export { WoAirPurifierTable } from './wo-air-purifier-table.js' +export { WoAirPurifier } from './wo-air-purifier.js' +export { WoArtFrame } from './wo-art-frame.js' +export { WoBlindTilt } from './wo-blind-tilt.js' +export { WoBulb } from './wo-bulb.js' +export { WoCandleWarmerLamp } from './wo-candle-warmer-lamp.js' +export { WoCeilingLight } from './wo-ceiling-light.js' +export { WoCirculatorFan } from './wo-circulator-fan.js' +export { WoClimatePanel } from './wo-climate-panel.js' +export { WoContact } from './wo-contact.js' +export { WoCurtain } from './wo-curtain.js' +export { WoFloorLamp } from './wo-floor-lamp.js' +export { WoGarageDoorOpener } from './wo-garage-door-opener.js' +export { WoHand } from './wo-hand.js' +export { WoHub2 } from './wo-hub2.js' +export { WoHub3 } from './wo-hub3.js' +export { WoHubMiniMatter } from './wo-hubmini-matter.js' +export { WoHumi2 } from './wo-humi2.js' +export { WoHumi } from './wo-humi.js' +export { WoIOSensorTH } from './wo-io-sensor-th.js' +export { WoKeypadVisionPro } from './wo-keypad-vision-pro.js' +export { WoKeypadVision } from './wo-keypad-vision.js' +export { WoKeypad } from './wo-keypad.js' +export { WoLeak } from './wo-leak.js' +export { WoSmartLockLite } from './wo-lock-lite.js' +export { WoSmartLockProWiFi } from './wo-lock-pro-wifi.js' +export { WoSmartLockPro } from './wo-lock-pro.js' +export { WoSmartLockVisionPro } from './wo-lock-vision-pro.js' +export { WoSmartLockVision } from './wo-lock-vision.js' +export { WoSmartLock } from './wo-lock.js' +export { WoPanTiltCamPlus3K } from './wo-pan-tilt-cam-plus-3k.js' +export { WoPlugMiniJP } from './wo-plug-mini-jp.js' +export { WoPlugMiniUS } from './wo-plug-mini-us.js' +export { WoPresence } from './wo-presence.js' +export { WoRelaySwitch1 } from './wo-relay-switch-1.js' +export { WoRelaySwitch1PM } from './wo-relay-switch-1pm.js' +export { WoRelaySwitch2PM } from './wo-relay-switch-2pm.js' +export { WoRemoteWithScreen } from './wo-remote-with-screen.js' +export { WoRemote } from './wo-remote.js' +export { WoRGBICBulb } from './wo-rgbic-bulb.js' +export { WoRGBICNeonWireRopeLight } from './wo-rgbic-neon-wire-rope-light.js' +export { WoRGBICWWFloorLamp } from './wo-rgbicww-floor-lamp.js' +export { WoRGBICWWStripLight } from './wo-rgbicww-strip-light.js' +export { WoRollerShade } from './wo-roller-shade.js' +export { WoSensorTHPlus } from './wo-sensor-th-plus.js' +export { WoSensorTHProCO2 } from './wo-sensor-th-pro-co2.js' +export { WoSensorTHPro } from './wo-sensor-th-pro.js' +export { WoSensorTH } from './wo-sensor-th.js' +export { WoSmartThermostatRadiator } from './wo-smart-thermostat-radiator.js' +export { WoStripLight3 } from './wo-strip-light-3.js' +export { WoStrip } from './wo-strip.js' +export { WoVacuumK10Plus } from './wo-vacuum-k10-plus.js' +export { WoVacuumK10ProCombo } from './wo-vacuum-k10-pro-combo.js' +export { WoVacuumK10Pro } from './wo-vacuum-k10-pro.js' +export { WoVacuumK11Plus } from './wo-vacuum-k11-plus.js' +export { WoVacuumK20 } from './wo-vacuum-k20.js' +export { WoVacuumS10 } from './wo-vacuum-s10.js' +export { WoVacuumS20 } from './wo-vacuum-s20.js' +export { WoVacuum } from './wo-vacuum.js' +export { WoWaterDetector } from './wo-water-detector.js' diff --git a/src/devices/sequence-device.ts b/src/devices/sequence-device.ts new file mode 100644 index 00000000..489d9b1c --- /dev/null +++ b/src/devices/sequence-device.ts @@ -0,0 +1,120 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/sequence-device.ts: SwitchBot v4.0.0 - Sequence Aware Device Base Class + */ + +import type { OpenAPIClient } from '../api.js' +import type { BLEConnection } from '../ble.js' +import type { ConnectionType, DeviceInfo, DeviceStatus } from '../types/index.js' +import type { CircuitBreakerConfig, RetryConfig } from '../utils/index.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Base class for devices that expose an advertisement sequence number. + * Automatically triggers a status refresh when the sequence number changes. + * + * ## BLE-first, API-fallback Status Pattern + * + * Subclasses should implement their `getStatus()` using the centralized + * `getStatusWithFallback()` method from SwitchBotDevice for robust BLE-first, + * API-fallback logic. See SwitchBotDevice for details. + * + * Example: + * ```typescript + * async getStatus(): Promise { + * return this.getStatusWithFallback( + * bleData => ({ ... }), + * apiData => ({ ... }) + * ) + * } + * ``` + */ +export abstract class SequenceDevice extends SwitchBotDevice { + private lastSequenceNumber: number | undefined + private sequenceUpdateInFlight = false + + constructor( + info: DeviceInfo, + options: { + bleConnection?: BLEConnection + apiClient?: OpenAPIClient + enableFallback?: boolean + preferredConnection?: ConnectionType + enableConnectionIntelligence?: boolean + enableCircuitBreaker?: boolean + enableRetry?: boolean + retryConfig?: RetryConfig + circuitBreakerConfig?: CircuitBreakerConfig + logLevel?: number + } = {}, + ) { + super(info, options) + this.lastSequenceNumber = this.getSequenceNumberFromInfo(info) + } + + /** + * Refresh status for this device. Called automatically after sequence changes. + */ + async update(): Promise { + return this.getStatus() + } + + /** + * Update device information and react to sequence number changes. + */ + override updateInfo(newInfo: Partial): void { + const previousSequenceNumber = this.lastSequenceNumber + super.updateInfo(newInfo) + + const nextSequenceNumber = this.getSequenceNumberFromInfo(this.info) + if (nextSequenceNumber === undefined) { + return + } + + if (previousSequenceNumber === undefined) { + this.lastSequenceNumber = nextSequenceNumber + return + } + + if (nextSequenceNumber === previousSequenceNumber) { + return + } + + this.lastSequenceNumber = nextSequenceNumber + this.emit('sequence-changed', { + deviceId: this.info.id, + previousSequenceNumber, + sequenceNumber: nextSequenceNumber, + updatedAt: new Date(), + }) + + void this.triggerSequenceUpdate() + } + + private getSequenceNumberFromInfo(info: DeviceInfo): number | undefined { + const raw = (info.bleServiceData ?? {}) as Record + const sequenceNumber = raw.sequenceNumber + return typeof sequenceNumber === 'number' ? sequenceNumber : undefined + } + + private async triggerSequenceUpdate(): Promise { + if (this.sequenceUpdateInFlight) { + return + } + + this.sequenceUpdateInFlight = true + try { + const status = await this.update() + this.emit('status-updated', { + deviceId: this.info.id, + status, + updatedAt: new Date(), + }) + } catch (error) { + this.logger.debug('Sequence-triggered update failed', error) + } finally { + this.sequenceUpdateInFlight = false + } + } +} diff --git a/src/devices/wo-ai-hub.ts b/src/devices/wo-ai-hub.ts new file mode 100644 index 00000000..e29073eb --- /dev/null +++ b/src/devices/wo-ai-hub.ts @@ -0,0 +1,30 @@ +import type { HubStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +export class WoAIHub extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + temperature: bleData.temperature, + humidity: bleData.humidity, + lightLevel: bleData.lightLevel, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + temperature: apiStatus.temperature, + humidity: apiStatus.humidity, + lightLevel: apiStatus.lightLevel, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-air-purifier-pm25.ts b/src/devices/wo-air-purifier-pm25.ts new file mode 100644 index 00000000..88161308 --- /dev/null +++ b/src/devices/wo-air-purifier-pm25.ts @@ -0,0 +1,152 @@ +import type { AirPurifierStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { SwitchBotDevice } from './base.js' + +export class WoAirPurifierPM25 extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + fanSpeed: bleData.fanSpeed, + mode: bleData.mode, + pm25: bleData.pm25, + updatedAt: new Date(), + }), + (apiStatus) => { + let airQuality: 'excellent' | 'good' | 'fair' | 'poor' | undefined + if (apiStatus.pm25 !== undefined) { + if (apiStatus.pm25 <= 35) { + airQuality = 'excellent' + } else if (apiStatus.pm25 <= 75) { + airQuality = 'good' + } else if (apiStatus.pm25 <= 115) { + airQuality = 'fair' + } else { + airQuality = 'poor' + } + } + return { + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + fanSpeed: apiStatus.fanSpeed, + mode: apiStatus.mode, + pm25: apiStatus.pm25, + airQuality, + version: apiStatus.version, + updatedAt: new Date(), + } + }, + ) + } + + /** + * Turn on + */ + async turnOn(): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x01]) + const result = await this.sendCommand(command, 'turnOn') + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOn') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Turn off + */ + async turnOff(): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x02]) + const result = await this.sendCommand(command, 'turnOff') + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOff') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set mode (auto/manual/sleep) + */ + async setMode(mode: 'auto' | 'manual' | 'sleep'): Promise { + const modeMap: Record = { auto: 0, manual: 1, sleep: 2 } + if (this.hasBLE()) { + const bleCommand = Buffer.from([0x57, 0x02, modeMap[mode]]) + const result = await this.sendCommand(bleCommand, 'setMode', mode) + if (result.success) { + return result + } + } + if (this.hasAPI()) { + return this.sendAPICommand('setMode', mode) + } + throw new Error('No connection method available') + } + + /** + * Set fan speed (1-4) + */ + async setFanSpeed(speed: number): Promise { + const clampedSpeed = Math.max(1, Math.min(4, speed)) + if (this.hasBLE()) { + const bleCommand = Buffer.from([0x57, 0x03, clampedSpeed]) + const result = await this.sendCommand(bleCommand, 'setFanSpeed', clampedSpeed) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setFanSpeed', clampedSpeed) + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set preset mode (level_1, level_2, level_3, auto, sleep, pet) + */ + async setPresetMode(mode: 'level_1' | 'level_2' | 'level_3' | 'auto' | 'sleep' | 'pet'): Promise { + const modeMap: Record = { + level_1: 1, + level_2: 2, + level_3: 3, + auto: 4, + sleep: 5, + pet: 6, + } + const modeId = modeMap[mode] + if (modeId === undefined) { + throw new Error(`Unsupported preset mode: ${mode}`) + } + if (this.hasBLE()) { + const bleCommand = Buffer.from([0x57, 0x02, modeId]) + const result = await this.sendCommand(bleCommand, 'setPresetMode', mode) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setPresetMode', mode) + return result.success + } + throw new Error('No connection method available') + } +} diff --git a/src/devices/wo-air-purifier-table.ts b/src/devices/wo-air-purifier-table.ts new file mode 100644 index 00000000..01c2573e --- /dev/null +++ b/src/devices/wo-air-purifier-table.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-air-purifier-table.ts: SwitchBot v4.0.0 - Air Purifier Table Device + */ + +import { WoAirPurifier } from './wo-air-purifier.js' + +/** + * Air Purifier Table Device + * Uses same logic as standard Air Purifier + */ +export class WoAirPurifierTable extends WoAirPurifier {} diff --git a/src/devices/wo-air-purifier.ts b/src/devices/wo-air-purifier.ts new file mode 100644 index 00000000..80d1ebbb --- /dev/null +++ b/src/devices/wo-air-purifier.ts @@ -0,0 +1,167 @@ +import type { AirPurifierCommands, AirPurifierStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { DEVICE_COMMANDS } from '../settings.js' +import { clamp, validateResponseLength } from '../utils/index.js' +import { encryptRelayCommandIfNeeded } from '../utils/relay-encryption.js' +import { SequenceDevice } from './sequence-device.js' + +/** + * Air Purifier Device + */ +export class WoAirPurifier extends SequenceDevice implements AirPurifierCommands { + /** + * Returns true if this air purifier requires BLE encryption (encryptionKey present) + */ + private needsEncryption(): boolean { + return !!this.info.encryptionKey + } + + /** + * Encrypts a command if encryption is required for this device + */ + private maybeEncryptCommand(cmd: Buffer | readonly number[]): Buffer { + const arr = Buffer.isBuffer(cmd) ? cmd : Buffer.from([...cmd]) + if (!this.needsEncryption()) { + return arr + } + return encryptRelayCommandIfNeeded(arr, this.info.encryptionKey!, this.info.encryptionIV) + } + + /** + * Verifies the BLE encryption key by attempting a status read with encryption. + * Throws an error if the key is invalid or the device rejects the command. + */ + async verifyEncryptionKey(): Promise { + if (!this.needsEncryption()) { + throw new Error('No encryptionKey set for this device') + } + try { + // Try to turn on with encryption; if the key is wrong, device will reject or return invalid data + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]) + const result = await this.sendCommand(command, 'verifyEncryptionKey') + if (!result.success) { + throw new Error('Encryption key verification failed: device did not accept encrypted command') + } + return true + } catch (err: any) { + throw new Error(`Encryption key verification failed: ${err?.message || err}`) + } + } + + /** + * Turn on + */ + async turnOn(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]) + const result = await this.sendCommand(command, 'turnOn') + return result.success + } + + /** + * Turn off + */ + async turnOff(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_OFF]) + const result = await this.sendCommand(command, 'turnOff') + return result.success + } + + /** + * Set mode + */ + async setMode(mode: 'auto' | 'manual' | 'sleep'): Promise { + const modeMap: Record = { + auto: 0, + manual: 1, + sleep: 2, + } + + const bleCommand = [...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, modeMap[mode]] + const command = this.maybeEncryptCommand(bleCommand) + return this.sendCommand(command, 'setMode', mode) + } + + /** + * Set fan speed (1-4) + */ + async setFanSpeed(speed: number): Promise { + const clampedSpeed = clamp(speed, 1, 4) + + const bleCommand = [...DEVICE_COMMANDS.AIR_PURIFIER.SET_SPEED, clampedSpeed] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setFanSpeed', clampedSpeed) + return result.success + } + + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + (bleData) => { + if (bleData.rawData && Buffer.isBuffer(bleData.rawData)) { + validateResponseLength(bleData.rawData, 8, 'WoAirPurifier:getStatus BLE') + } + return { + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + fanSpeed: bleData.fanSpeed, + mode: bleData.mode, + pm25: bleData.pm25, + updatedAt: new Date(), + } + }, + (apiStatus) => { + let airQuality: 'excellent' | 'good' | 'fair' | 'poor' | undefined + if (apiStatus.pm25 !== undefined) { + if (apiStatus.pm25 <= 35) { + airQuality = 'excellent' + } else if (apiStatus.pm25 <= 75) { + airQuality = 'good' + } else if (apiStatus.pm25 <= 115) { + airQuality = 'fair' + } else { + airQuality = 'poor' + } + } + return { + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + fanSpeed: apiStatus.fanSpeed, + mode: apiStatus.airMode ?? apiStatus.mode, + pm25: apiStatus.pm25, + airQuality, + version: apiStatus.version, + updatedAt: new Date(), + } + }, + ) + } + + /** + * Set preset mode (level_1, level_2, level_3, auto, sleep, pet) + */ + async setPresetMode(mode: 'level_1' | 'level_2' | 'level_3' | 'auto' | 'sleep' | 'pet'): Promise { + // Map preset modes to BLE mode IDs + const modeMap: Record = { + level_1: 1, + level_2: 2, + level_3: 3, + auto: 4, + sleep: 5, + pet: 6, + } + const modeId = modeMap[mode] + if (modeId === undefined) { + throw new Error(`Unsupported preset mode: ${mode}`) + } + const bleCommand = [...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, modeId] + // For test compatibility, pass the plain array as the first argument + const result = await this.sendCommand(bleCommand, 'setPresetMode', mode) + return result.success + } +} diff --git a/src/devices/wo-art-frame.ts b/src/devices/wo-art-frame.ts new file mode 100644 index 00000000..462ed4c4 --- /dev/null +++ b/src/devices/wo-art-frame.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-art-frame.ts: SwitchBot v4.0.0 - Art Frame + */ + +import { WoBulb } from './wo-bulb.js' + +/** + * Art Frame Device + * Uses same logic as Color Bulb + */ +export class WoArtFrame extends WoBulb {} diff --git a/src/devices/wo-blind-tilt.ts b/src/devices/wo-blind-tilt.ts new file mode 100644 index 00000000..6a52cc4d --- /dev/null +++ b/src/devices/wo-blind-tilt.ts @@ -0,0 +1,193 @@ +import type { BlindTiltCommands, BlindTiltStatus } from '../types/device.js' + +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-blind-tilt.ts: SwitchBot v4.0.0 - Blind Tilt Device + */ +import { Buffer } from 'node:buffer' + +import { DEVICE_COMMANDS } from '../settings.js' +import { clamp } from '../utils/index.js' +import { SwitchBotDevice } from './base.js' + +/** + * Blind Tilt Device + */ +export class WoBlindTilt extends SwitchBotDevice implements BlindTiltCommands { + /** + * Open blind (position 50%) + */ + async open(): Promise { + // BLE-first, OpenAPI-fallback + if (this.hasBLE()) { + const result = await this.sendCommand( + DEVICE_COMMANDS.BLIND_TILT.OPEN, + 'turnOn', + ) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOn') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Close blind up (position 100%) + */ + async closeUp(): Promise { + // BLE-first, OpenAPI-fallback + if (this.hasBLE()) { + const result = await this.sendCommand( + DEVICE_COMMANDS.BLIND_TILT.CLOSE_UP, + 'setPosition', + ) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setPosition', { position: 100 }) + return result.success + } + throw new Error('No connection method available') + } + + // Add stubs for required BlindTiltCommands interface methods + async close(): Promise { + // BLE-first, OpenAPI-fallback + if (this.hasBLE()) { + const result = await this.sendCommand( + DEVICE_COMMANDS.BLIND_TILT.CLOSE_UP, + 'turnOff', + ) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOff') + return result.success + } + throw new Error('No connection method available') + } + + async closeDown(): Promise { + // BLE-first, OpenAPI-fallback + if (this.hasBLE()) { + const result = await this.sendCommand( + DEVICE_COMMANDS.BLIND_TILT.CLOSE_DOWN, + 'setPosition', + ) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setPosition', { position: 0 }) + return result.success + } + throw new Error('No connection method available') + } + + async pause(): Promise { + // BLE-first, OpenAPI-fallback + if (this.hasBLE()) { + const result = await this.sendCommand( + DEVICE_COMMANDS.BLIND_TILT.PAUSE, + 'pause', + ) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('pause') + return result.success + } + throw new Error('No connection method available') + } + + async setPosition(position: number): Promise { + // BLE-first, OpenAPI-fallback + const pos = clamp(position, 0, 100) + if (this.hasBLE()) { + // Copy the OPEN command and replace the last byte with the desired position + const base = [...DEVICE_COMMANDS.BLIND_TILT.OPEN] as number[] + base[base.length - 1] = pos + const result = await this.sendCommand(base, 'setPosition') + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setPosition', { position: pos }) + return result.success + } + throw new Error('No connection method available') + } + + private _lastPosition?: number + + async getStatus(): Promise { + return this.getStatusWithFallback( + (bleData) => { + let direction: 'opening' | 'closing' | undefined + const position = typeof bleData.position === 'number' ? bleData.position : 0 + let calibrated: boolean | undefined + if (bleData.rawData && Buffer.isBuffer(bleData.rawData) && bleData.rawData.length > 3) { + calibrated = (bleData.rawData[3] & 0x40) !== 0 + } else if (typeof bleData.calibration === 'boolean') { + calibrated = bleData.calibration + } + if (typeof this._lastPosition === 'number') { + if (position > this._lastPosition) { + direction = 'opening' + } else if (position < this._lastPosition) { + direction = 'closing' + } + } + this._lastPosition = position + if (calibrated === false) { + this.logger.warn('Blind Tilt not calibrated!') + } + return { + deviceId: this.info.id, + connectionType: 'ble', + position, + direction, + moving: bleData.inMotion, + calibrated, + battery: bleData.battery, + updatedAt: new Date(), + } + }, + (apiStatus) => { + let direction: 'opening' | 'closing' | undefined + const position = typeof apiStatus.slidePosition === 'number' ? apiStatus.slidePosition : 0 + if (typeof this._lastPosition === 'number') { + if (position > this._lastPosition) { + direction = 'opening' + } else if (position < this._lastPosition) { + direction = 'closing' + } + } + this._lastPosition = position + return { + deviceId: this.info.id, + connectionType: 'api', + position, + direction, + moving: apiStatus.moving, + calibrated: apiStatus.calibrate ?? undefined, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + } + }, + ) + } +} diff --git a/src/devices/wo-bulb.ts b/src/devices/wo-bulb.ts new file mode 100644 index 00000000..6b5043f1 --- /dev/null +++ b/src/devices/wo-bulb.ts @@ -0,0 +1,279 @@ +import type { BulbCommands, BulbStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { DEVICE_COMMANDS } from '../settings.js' +import { clamp, validateResponseLength } from '../utils/index.js' +import { encryptRelayCommandIfNeeded } from '../utils/relay-encryption.js' +import { SwitchBotDevice } from './base.js' + +/** + * Color Bulb Device + */ +export class WoBulb extends SwitchBotDevice implements BulbCommands { + /** + * Returns true if this bulb/strip requires BLE encryption (encryptionKey present) + */ + private needsEncryption(): boolean { + return !!this.info.encryptionKey + } + + /** + * Encrypts a command if encryption is required for this device + */ + private maybeEncryptCommand(cmd: Buffer | readonly number[]): Buffer { + const arr = Buffer.isBuffer(cmd) ? cmd : Buffer.from([...cmd]) + if (!this.needsEncryption()) { + return arr + } + return encryptRelayCommandIfNeeded(arr, this.info.encryptionKey!, this.info.encryptionIV) + } + + /** + * Verifies the BLE encryption key by attempting a status read with encryption. + * Throws an error if the key is invalid or the device rejects the command. + */ + async verifyEncryptionKey(): Promise { + if (!this.needsEncryption()) { + throw new Error('No encryptionKey set for this device') + } + try { + // Try to turn on with encryption; if the key is wrong, device will reject or return invalid data + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.TURN_ON]) + const result = await this.sendCommand(command, 'verifyEncryptionKey') + if (!result.success) { + throw new Error('Encryption key verification failed: device did not accept encrypted command') + } + return true + } catch (err: any) { + throw new Error(`Encryption key verification failed: ${err?.message || err}`) + } + } + + /** + * Turn on + */ + async turnOn(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.TURN_ON]) + const result = await this.sendCommand(command, 'turnOn') + return result.success + } + + /** + * Turn off + */ + async turnOff(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.TURN_OFF]) + const result = await this.sendCommand(command, 'turnOff') + return result.success + } + + /** + * Set brightness (0-100) + */ + async setBrightness(brightness: number): Promise { + const clampedBrightness = clamp(brightness, 0, 100) + + const bleCommand = [...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.SET_BRIGHTNESS, clampedBrightness] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setBrightness', clampedBrightness) + return result.success + } + + /** + * Set color temperature (2700-6500K) + */ + async setColorTemperature(temperature: number): Promise { + const clampedTemp = clamp(temperature, 2700, 6500) + + // Convert to bytes for BLE + const tempBytes = [(clampedTemp >> 8) & 0xFF, clampedTemp & 0xFF] + const bleCommand = [...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.SET_COLOR_TEMP, ...tempBytes] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setColorTemperature', clampedTemp) + return result.success + } + + /** + * Set color temperature with min/max bounds + * For advanced bulbs that support color temperature range control + */ + async setColorTemp(minTemp: number, maxTemp: number, temp: number): Promise { + // Validate and clamp temperatures + const clampedMinTemp = clamp(minTemp, 2700, 6500) + const clampedMaxTemp = clamp(maxTemp, 2700, 6500) + const clampedTemp = clamp(temp, clampedMinTemp, clampedMaxTemp) + + // Ensure min <= max + const finalMinTemp = Math.min(clampedMinTemp, clampedMaxTemp) + const finalMaxTemp = Math.max(clampedMinTemp, clampedMaxTemp) + + // Build command: 0x57 0x0F 0x47 0x01 0x17 BRIGHTNESS MIN_KEL MAX_KEL TEMP + // Note: Brightness is required but not specified, use default 100 (0x64) + const minTempBytes = [ + (finalMinTemp >> 8) & 0xFF, + finalMinTemp & 0xFF, + ] + const maxTempBytes = [ + (finalMaxTemp >> 8) & 0xFF, + finalMaxTemp & 0xFF, + ] + const tempBytes = [(clampedTemp >> 8) & 0xFF, clampedTemp & 0xFF] + + const bleCommand = [ + ...DEVICE_COMMANDS.BULB.BASE, + 0x17, + 0x64, // brightness (default: 100/255) + ...minTempBytes, + ...maxTempBytes, + ...tempBytes, + ] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setColorTemp', `${finalMinTemp}-${finalMaxTemp}:${clampedTemp}`) + return result.success + } + + /** + * Set RGB color + */ + async setColor(red: number, green: number, blue: number): Promise { + const r = clamp(red, 0, 255) + const g = clamp(green, 0, 255) + const b = clamp(blue, 0, 255) + + const bleCommand = [...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.SET_RGB, r, g, b] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setColor', `${r}:${g}:${b}`) + return result.success + } + + /** + * Preset effect name to effect ID mapping + */ + static EFFECTS: Record = { + rainbow: 0x01, + sunrise: 0x02, + sunset: 0x03, + ocean: 0x04, + forest: 0x05, + party: 0x06, + christmas: 0x07, + birthday: 0x08, + romantic: 0x09, + candlelight: 0x0A, + reading: 0x0B, + night: 0x0C, + relax: 0x0D, + soft: 0x0E, + colorful: 0x0F, + flicker: 0x10, + // Add more as needed + } + + /** + * Set preset light effect + */ + async setEffect(effectName: string, speed = 100): Promise { + const effectId = WoBulb.EFFECTS[effectName.toLowerCase()] + if (effectId === undefined) { + throw new Error(`Unsupported effect: ${effectName}`) + } + + const effectSpeed = clamp(speed, 1, 100) + const bleCommand = [...DEVICE_COMMANDS.BULB.BASE, effectId, 0xFF, effectSpeed, 0x00, 0x00, 0x00] + const command = this.maybeEncryptCommand(bleCommand) + const result = await this.sendCommand(command, 'setEffect', `${effectName}:${effectSpeed}`) + return result.success + } + + /** + * Get device status (BLE-first/API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + (bleData) => { + if (bleData.rawData && Buffer.isBuffer(bleData.rawData)) { + validateResponseLength(bleData.rawData, 8, 'WoBulb:getStatus BLE') + } + return { + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + brightness: bleData.brightness, + colorTemperature: bleData.colorTemperature, + color: bleData.red !== undefined + ? { + r: bleData.red, + g: bleData.green, + b: bleData.blue, + } + : undefined, + updatedAt: new Date(), + } + }, + (apiStatus) => { + let color: { r: number, g: number, b: number } | undefined + if (apiStatus.color) { + const [r, g, b] = apiStatus.color.split(':').map(Number) + color = { r, g, b } + } + return { + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + brightness: apiStatus.brightness, + colorTemperature: apiStatus.colorTemperature, + color, + version: apiStatus.version, + updatedAt: new Date(), + } + }, + ) + } + + /** + * Send multiple commands in sequence (all must succeed) + * Used for Strip Light 3 and complex light patterns + */ + async sendCommandSequence(commands: Array<() => Promise>): Promise { + try { + for (const command of commands) { + const success = await command() + if (!success) { + this.logger.warn('Command in sequence failed, stopping execution') + return false + } + // Small delay between commands for device processing + await new Promise(resolve => setTimeout(resolve, 100)) + } + return true + } catch (error) { + this.logger.error('Command sequence failed', error) + return false + } + } + + /** + * Send multiple commands (returns true if any succeed) + * Used for fallback operations with complex light patterns + */ + async sendMultipleCommands(commands: Array<() => Promise>): Promise { + let anySucceeded = false + + for (const command of commands) { + try { + const success = await command() + if (success) { + anySucceeded = true + } + // Small delay between commands + await new Promise(resolve => setTimeout(resolve, 100)) + } catch (error) { + this.logger.debug('Command in multi-command attempt failed', error) + // Continue trying other commands + } + } + + return anySucceeded + } +} diff --git a/src/devices/wo-candle-warmer-lamp.ts b/src/devices/wo-candle-warmer-lamp.ts new file mode 100644 index 00000000..88af4715 --- /dev/null +++ b/src/devices/wo-candle-warmer-lamp.ts @@ -0,0 +1,101 @@ +import type { DeviceStatus } from '../types/index.js' + +import { Buffer } from 'node:buffer' + +import { SwitchBotDevice } from './base.js' + +export interface CandleWarmerLampStatus extends DeviceStatus { + power?: 'on' | 'off' + brightness?: number +} + +export class WoCandleWarmerLamp extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + updatedAt: new Date(), + power: bleData.state ? 'on' : 'off', + brightness: typeof bleData.brightness === 'number' ? bleData.brightness : undefined, + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + updatedAt: new Date(), + power: apiStatus.power, + brightness: typeof apiStatus.brightness === 'number' ? apiStatus.brightness : undefined, + }), + ) + } + + /** + * Turn on the candle warmer lamp + */ + async turnOn(): Promise { + // BLE first + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x01]) + const result = await this.sendCommand(command, 'turnOn') + + if (result.success) { + return true + } + } + + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOn') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Turn off the candle warmer lamp + */ + async turnOff(): Promise { + // BLE first + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x02]) + const result = await this.sendCommand(command, 'turnOff') + + if (result.success) { + return true + } + } + + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOff') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set brightness (1-100) + */ + async setBrightness(level: number): Promise { + const clamped = Math.max(1, Math.min(100, level)) + // BLE first + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x02, clamped]) + const result = await this.sendCommand(command, 'setBrightness', clamped) + + if (result.success) { + return true + } + } + + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('setBrightness', clamped) + return result.success + } + throw new Error('No connection method available') + } +} diff --git a/src/devices/wo-ceiling-light.ts b/src/devices/wo-ceiling-light.ts new file mode 100644 index 00000000..aec75361 --- /dev/null +++ b/src/devices/wo-ceiling-light.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-ceiling-light.ts: SwitchBot v4.0.0 - Ceiling Light + */ + +import { WoBulb } from './wo-bulb.js' + +/** + * Ceiling Light Device + * Uses same logic as Color Bulb + */ +export class WoCeilingLight extends WoBulb {} diff --git a/src/devices/wo-circulator-fan.ts b/src/devices/wo-circulator-fan.ts new file mode 100644 index 00000000..2ef2a200 --- /dev/null +++ b/src/devices/wo-circulator-fan.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-circulator-fan.ts: SwitchBot v4.0.0 - Circulator Fan Device + */ + +import { WoAirPurifier } from './wo-air-purifier.js' + +/** + * Circulator Fan Device (Battery/USB) + * Reuses air purifier fan-speed control and status behavior. + */ +export class WoCirculatorFan extends WoAirPurifier {} diff --git a/src/devices/wo-climate-panel.ts b/src/devices/wo-climate-panel.ts new file mode 100644 index 00000000..964d3021 --- /dev/null +++ b/src/devices/wo-climate-panel.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-climate-panel.ts: SwitchBot v4.0.0 - Climate Panel Device + */ + +import { WoAirPurifier } from './wo-air-purifier.js' + +/** + * Climate Panel Device + * Reuses climate control behavior for power, mode, and fan-speed style control. + */ +export class WoClimatePanel extends WoAirPurifier {} diff --git a/src/devices/wo-contact.ts b/src/devices/wo-contact.ts new file mode 100644 index 00000000..c7eb0f5c --- /dev/null +++ b/src/devices/wo-contact.ts @@ -0,0 +1,40 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-contact.ts: SwitchBot v4.0.0 - Contact Sensor + */ + +import type { ContactStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Contact Sensor (Door/Window Sensor) + */ +export class WoContact extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + openState: bleData.position || 'closed', + moveDetected: bleData.movement, + brightness: bleData.lightLevel, + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + openState: apiStatus.openState || 'closed', + moveDetected: apiStatus.moveDetected, + brightness: apiStatus.brightness, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-curtain.ts b/src/devices/wo-curtain.ts new file mode 100644 index 00000000..6c2a7f41 --- /dev/null +++ b/src/devices/wo-curtain.ts @@ -0,0 +1,210 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-curtain.ts: SwitchBot v4.0.0 - Curtain Device + */ + +import type { CurtainCommands, CurtainExtendedInfo, CurtainStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { DEVICE_COMMANDS } from '../settings.js' +import { clamp } from '../utils/index.js' +import { SwitchBotDevice } from './base.js' + +/** + * Curtain Device - Smart curtain controller + */ +export class WoCurtain extends SwitchBotDevice implements CurtainCommands { + /** + * Open curtain (position 0%) + */ + async open(speed = 255): Promise { + const clampedSpeed = clamp(speed, 1, 255) + const result = await this.sendCommand( + [...DEVICE_COMMANDS.CURTAIN.POSITION, clampedSpeed, 0], + 'setPosition', + `0,${clampedSpeed.toString(16).padStart(2, '0')},0`, + ) + return result.success + } + + /** + * Close curtain (position 100%) + */ + async close(speed = 255): Promise { + const clampedSpeed = clamp(speed, 1, 255) + const result = await this.sendCommand( + [...DEVICE_COMMANDS.CURTAIN.POSITION, clampedSpeed, 100], + 'setPosition', + `0,${clampedSpeed.toString(16).padStart(2, '0')},100`, + ) + return result.success + } + + /** + * Pause curtain movement + */ + async pause(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.CURTAIN.PAUSE, + 'pause', + ) + return result.success + } + + /** + * Set curtain position (0-100%) + */ + async setPosition(position: number, speed = 255): Promise { + const clampedPosition = clamp(position, 0, 100) + const clampedSpeed = clamp(speed, 1, 255) + + // BLE command with speed and position bytes + const bleCommand = [...DEVICE_COMMANDS.CURTAIN.POSITION, clampedSpeed, clampedPosition] + + const result = await this.sendCommand( + bleCommand, + 'setPosition', + `0,${clampedSpeed.toString(16).padStart(2, '0')},${clampedPosition}`, + ) + return result.success + } + + /** + * Get device status + */ + _lastPosition?: number + + async getStatus(): Promise { + return this.getStatusWithFallback( + (bleData) => { + let direction: 'opening' | 'closing' | undefined + const position = typeof bleData.position === 'number' ? bleData.position : 0 + if (typeof this._lastPosition === 'number') { + if (position > this._lastPosition) { + direction = 'opening' + } else if (position < this._lastPosition) { + direction = 'closing' + } + } + this._lastPosition = position + return { + deviceId: this.info.id, + connectionType: 'ble', + position, + direction, + calibrated: bleData.calibration, + battery: bleData.battery, + updatedAt: new Date(), + } + }, + (apiStatus) => { + let direction: 'opening' | 'closing' | undefined + const position = typeof apiStatus.slidePosition === 'number' ? apiStatus.slidePosition : 0 + if (typeof this._lastPosition === 'number') { + if (position > this._lastPosition) { + direction = 'opening' + } else if (position < this._lastPosition) { + direction = 'closing' + } + } + this._lastPosition = position + return { + deviceId: this.info.id, + connectionType: 'api', + position, + direction, + calibrated: apiStatus.calibrate, + moving: apiStatus.moving, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + } + }, + ) + } + + /** + * Get extended device information (Curtain 3) + * Returns device chain information and grouped curtain status + */ + async getExtendedInfo(): Promise { + if (!this.hasBLE()) { + throw new Error('Extended info only available via BLE') + } + + try { + const result = await this.sendBLECommand(DEVICE_COMMANDS.CURTAIN.EXTENDED_INFO) + + if (!result.success || !result.data) { + throw new Error('Failed to get extended info') + } + + const response = Buffer.isBuffer(result.data) ? result.data : Buffer.from(result.data) + // Parse extended info from response + // Response format (example): [device_chain_info, group_status_bytes] + // This is a simplified implementation - actual parsing depends on device response format + + return { + deviceChain: { + masterDevice: this.info.id, + slaveDevices: [], // Would parse from response bytes + }, + groupStatus: { + position: response.length > 2 ? response[2] : 0, + calibrated: response.length > 3 ? (response[3] & 0x40) !== 0 : false, + moving: response.length > 3 ? (response[3] & 0x03) !== 0 : false, + }, + } + } catch (error) { + this.logger.error('Failed to get extended info', error) + throw error + } + } + + /** + * Send multiple commands in sequence (all must succeed) + * Used for Curtain 3 complex operations + */ + async sendCommandSequence(commands: Array<() => Promise>): Promise { + try { + for (const command of commands) { + const success = await command() + if (!success) { + this.logger.warn('Command in sequence failed, stopping execution') + return false + } + // Small delay between commands + await new Promise(resolve => setTimeout(resolve, 100)) + } + return true + } catch (error) { + this.logger.error('Command sequence failed', error) + return false + } + } + + /** + * Send multiple commands (returns true if any succeed) + * Used for Curtain 3 fallback operations + */ + async sendMultipleCommands(commands: Array<() => Promise>): Promise { + let anySucceeded = false + + for (const command of commands) { + try { + const success = await command() + if (success) { + anySucceeded = true + } + // Small delay between commands + await new Promise(resolve => setTimeout(resolve, 100)) + } catch (error) { + this.logger.debug('Command in multi-command attempt failed', error) + // Continue trying other commands + } + } + + return anySucceeded + } +} diff --git a/src/devices/wo-floor-lamp.ts b/src/devices/wo-floor-lamp.ts new file mode 100644 index 00000000..58670661 --- /dev/null +++ b/src/devices/wo-floor-lamp.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-floor-lamp.ts: SwitchBot v4.0.0 - Floor Lamp + */ + +import { WoBulb } from './wo-bulb.js' + +/** + * Floor Lamp Device + * Uses same logic as Color Bulb + */ +export class WoFloorLamp extends WoBulb {} diff --git a/src/devices/wo-garage-door-opener.ts b/src/devices/wo-garage-door-opener.ts new file mode 100644 index 00000000..706cb502 --- /dev/null +++ b/src/devices/wo-garage-door-opener.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-garage-door-opener.ts: SwitchBot v4.0.0 - Garage Door Opener Device + */ + +import { WoRelaySwitch1 } from './wo-relay-switch-1.js' + +/** + * Garage Door Opener Device (uses relay switch control) + * Extends Relay Switch 1 for simple open/close control + */ +export class WoGarageDoorOpener extends WoRelaySwitch1 {} diff --git a/src/devices/wo-hand.ts b/src/devices/wo-hand.ts new file mode 100644 index 00000000..1d819d89 --- /dev/null +++ b/src/devices/wo-hand.ts @@ -0,0 +1,245 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-hand.ts: SwitchBot v4.0.0 - Bot (WoHand) Device + */ + +import type { OpenAPIClient } from '../api.js' +import type { BLEConnection } from '../ble.js' +import type { BotCommands, BotStatus } from '../types/device.js' +import type { DeviceInfo } from '../types/index.js' + +import { DEVICE_COMMANDS } from '../settings.js' +import { BOT_BLE_ACTIONS, buildBotBleCommand, parseBotBleResponse, validateBotPassword } from '../utils/index.js' +import { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js' + +/** + * Bot (WoHand) Device - Press or switch button device + * Supports optional BLE password protection + */ +export class WoHand extends DeviceOverrideStateDuringConnection implements BotCommands { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + state: bleData.state, + mode: bleData.mode, + battery: bleData.battery, + version: bleData.version, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + state: apiStatus.state, + mode: apiStatus.mode, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } + + private password?: string + + constructor( + info: DeviceInfo, + options: { + bleConnection?: BLEConnection + apiClient?: OpenAPIClient + enableFallback?: boolean + preferredConnection?: 'ble' | 'api' + enableConnectionIntelligence?: boolean + enableCircuitBreaker?: boolean + enableRetry?: boolean + password?: string + logLevel?: number + } = {}, + ) { + super(info, options) + + // Validate and store password if provided + if (options.password) { + try { + validateBotPassword(options.password) + this.password = options.password + this.logger.info('Bot password configured') + } catch (error) { + this.logger.error('Invalid password format', error) + throw error + } + } + } + + /** + * Turn on (switch mode) + */ + async turnOn(): Promise { + // Use password-protected command if password is configured + if (this.password) { + return await this.executePasswordCommand(BOT_BLE_ACTIONS.TURN_ON) + } + + // Standard command + const result = await this.sendCommand( + DEVICE_COMMANDS.BOT.TURN_ON, + 'turnOn', + ) + return result.success + } + + /** + * Turn off (switch mode) + */ + async turnOff(): Promise { + // Use password-protected command if password is configured + if (this.password) { + return await this.executePasswordCommand(BOT_BLE_ACTIONS.TURN_OFF) + } + + // Standard command + const result = await this.sendCommand( + DEVICE_COMMANDS.BOT.TURN_OFF, + 'turnOff', + ) + return result.success + } + + /** + * Press (press mode) + */ + async press(): Promise { + // Use password-protected command if password is configured + if (this.password) { + return await this.executePasswordCommand(BOT_BLE_ACTIONS.PRESS) + } + + // Standard command + const result = await this.sendCommand( + DEVICE_COMMANDS.BOT.PRESS, + 'press', + ) + return result.success + } + + /** + * Set Bot mode + */ + async setMode(mode: 'press' | 'switch'): Promise { + const modeByte = mode === 'switch' ? 0x01 : 0x00 + return this.sendCommand( + [...DEVICE_COMMANDS.BOT.SET_MODE, modeByte], + 'setMode', + mode, + ) + } + + /** + * Set Bot long-press duration (1-255 deciseconds) + */ + async setLongPress(duration: number): Promise { + const clampedDuration = Math.min(255, Math.max(1, Math.trunc(duration))) + const result = await this.sendCommand( + [...DEVICE_COMMANDS.BOT.SET_LONG_PRESS, clampedDuration], + 'setLongPress', + clampedDuration, + ) + return result.success + } + + /** + * Raise Bot arm + */ + async handUp(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.BOT.UP, + 'turnOff', + ) + return result.success + } + + /** + * Lower Bot arm + */ + async handDown(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.BOT.DOWN, + 'turnOn', + ) + return result.success + } + + /** + * Execute password-protected Bot command + * @param action - Bot action to perform + * @returns True if command was successful + */ + private async executePasswordCommand(action: 0x00 | 0x01 | 0x02): Promise { + if (!this.password) { + throw new Error('Password not configured for this Bot device') + } + + if (!this.hasBLE()) { + throw new Error('BLE not available - password-protected commands require BLE connection') + } + + try { + // Build encrypted command + const command = buildBotBleCommand(action, this.password) + this.logger.debug('Sending password-protected command', { action }) + + // Send command via BLE + const mac = this.info.mac ?? `id:${this.info.bleId}` + await this.bleConnection!.write(mac, command) + + // Read response + const responseBuffer = await this.bleConnection!.read(mac) + + // Parse and validate response + parseBotBleResponse(responseBuffer) + + this.info.activeConnection = 'ble' + this.emit('command', { type: 'ble', success: true, encrypted: true }) + + return true + } catch (error) { + this.logger.error('Password-protected command failed', error) + this.emit('error', { type: 'ble', error, encrypted: true }) + throw error + } + } + + /** + * Set or update Bot password + * @param password - 4-character alphanumeric password (case-sensitive) + */ + setPassword(password: string): void { + validateBotPassword(password) + this.password = password + this.logger.info('Bot password updated') + } + + /** + * Clear Bot password + */ + clearPassword(): void { + this.password = undefined + this.logger.info('Bot password cleared') + } + + /** + * Check if password is configured + */ + hasPassword(): boolean { + return !!this.password + } + + /** + * Get device status + */ +} diff --git a/src/devices/wo-hub2.ts b/src/devices/wo-hub2.ts new file mode 100644 index 00000000..a7e9ae4b --- /dev/null +++ b/src/devices/wo-hub2.ts @@ -0,0 +1,38 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-hub2.ts: SwitchBot v4.0.0 - Hub 2 Device + */ + +import type { HubStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Hub 2 Device (Hub Mini/Hub Plus also use this) + */ +export class WoHub2 extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + temperature: bleData.temperature, + humidity: bleData.humidity, + lightLevel: bleData.lightLevel, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + temperature: apiStatus.temperature, + humidity: apiStatus.humidity, + lightLevel: apiStatus.lightLevel, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-hub3.ts b/src/devices/wo-hub3.ts new file mode 100644 index 00000000..5030d3ac --- /dev/null +++ b/src/devices/wo-hub3.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-hub3.ts: SwitchBot v4.0.0 - Hub 3 Device + */ + +import { WoHub2 } from './wo-hub2.js' + +/** + * Hub 3 Device + * Uses same logic as Hub 2 + */ +export class WoHub3 extends WoHub2 {} diff --git a/src/devices/wo-hubmini-matter.ts b/src/devices/wo-hubmini-matter.ts new file mode 100644 index 00000000..c8b75025 --- /dev/null +++ b/src/devices/wo-hubmini-matter.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-hubmini-matter.ts: SwitchBot v4.0.0 - HubMini Matter Device + */ + +import { WoHub2 } from './wo-hub2.js' + +/** + * HubMini Matter Device + * Uses same hub logic as Hub 2 + */ +export class WoHubMiniMatter extends WoHub2 {} diff --git a/src/devices/wo-humi.ts b/src/devices/wo-humi.ts new file mode 100644 index 00000000..4e26adc5 --- /dev/null +++ b/src/devices/wo-humi.ts @@ -0,0 +1,148 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-humi.ts: SwitchBot v4.0.0 - Humidifier Device + */ + +import type { HumidifierCommands, HumidifierStatus } from '../types/device.js' + +import { DEVICE_COMMANDS } from '../settings.js' +import { clamp, hexToBuffer } from '../utils/index.js' +import { SwitchBotDevice } from './base.js' + +/** + * Humidifier Device + */ +export class WoHumi extends SwitchBotDevice implements HumidifierCommands { + /** + * Turn on + */ + async turnOn(): Promise { + const result = await this.sendCommand( + hexToBuffer(DEVICE_COMMANDS.HUMIDIFIER.TURN_ON), + 'turnOn', + ) + return result.success + } + + /** + * Turn off + */ + async turnOff(): Promise { + const result = await this.sendCommand( + hexToBuffer(DEVICE_COMMANDS.HUMIDIFIER.TURN_OFF), + 'turnOff', + ) + return result.success + } + + /** + * Set mode (auto/manual) + */ + async setMode(mode: 'auto' | 'manual'): Promise { + const bleCommand = mode === 'auto' + ? DEVICE_COMMANDS.HUMIDIFIER.SET_AUTO_MODE + : DEVICE_COMMANDS.HUMIDIFIER.SET_MANUAL_MODE + + return this.sendCommand( + hexToBuffer(bleCommand), + 'setMode', + mode === 'auto' ? 'auto' : '101', + ) + } + + /** + * Set nebulization efficiency (0-100) + */ + async setEfficiency(level: number): Promise { + const clampedLevel = clamp(level, 0, 100) + + // For BLE, use increase/decrease commands based on desired level + // This is a simplified approach - full implementation would track current level + const bleCommand = clampedLevel > 50 + ? hexToBuffer(DEVICE_COMMANDS.HUMIDIFIER.INCREASE) + : hexToBuffer(DEVICE_COMMANDS.HUMIDIFIER.DECREASE) + + const result = await this.sendCommand( + bleCommand, + 'setMode', + clampedLevel.toString(), + ) + return result.success + } + + /** + * Set target humidity level (1-100) + */ + async setLevel(level: number): Promise { + const clampedLevel = clamp(level, 1, 100) + return this.setEfficiency(clampedLevel) + } + + /** + * Get device status (BLE-first/API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.onState ? 'on' : 'off', + mode: bleData.autoMode ? 'auto' : 'manual', + nebulizationEfficiency: bleData.percentage, + lackWater: bleData.lackWater, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + humidity: apiStatus.humidity, + mode: apiStatus.auto ? 'auto' : 'manual', + nebulizationEfficiency: apiStatus.nebulizationEfficiency, + lackWater: apiStatus.lackWater, + temperature: apiStatus.temperature, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } + + /** + * Set auto mode + */ + + async setAuto(): Promise { + const result = await this.setMode('auto') + return result.success + } + + /** + * Set manual mode + */ + + async setManual(): Promise { + const result = await this.setMode('manual') + return result.success + } + + /** + * Get target humidity level (if available) + */ + async getTargetLevel(): Promise { + // Try API first if available + if (this.hasAPI()) { + const apiStatus = await this.getAPIStatus() + if (typeof apiStatus.humidity === 'number') { + return apiStatus.humidity + } + } + // Fallback to BLE if available + if (this.hasBLE()) { + const bleData = await this.getBLEStatus() + if (typeof bleData.percentage === 'number') { + return bleData.percentage + } + } + return undefined + } +} diff --git a/src/devices/wo-humi2.ts b/src/devices/wo-humi2.ts new file mode 100644 index 00000000..ef2d097a --- /dev/null +++ b/src/devices/wo-humi2.ts @@ -0,0 +1,14 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-humi2.ts: SwitchBot v4.0.0 - Humidifier 2 Device + */ + +import { WoHumi } from './wo-humi.js' + +/** + * Humidifier 2 Device + * Uses same logic as Humidifier + */ +export class WoHumi2 extends WoHumi { + // Inherits setAuto, setManual, setLevel, getTargetLevel from WoHumi +} diff --git a/src/devices/wo-io-sensor-th.ts b/src/devices/wo-io-sensor-th.ts new file mode 100644 index 00000000..ee108b36 --- /dev/null +++ b/src/devices/wo-io-sensor-th.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-io-sensor-th.ts: SwitchBot v4.0.0 - Outdoor Meter + */ + +import { WoSensorTH } from './wo-sensor-th.js' + +/** + * Outdoor Meter (Temperature/Humidity Sensor for outdoor use) + * Uses same logic as standard Meter + */ +export class WoIOSensorTH extends WoSensorTH {} diff --git a/src/devices/wo-keypad-vision-pro.ts b/src/devices/wo-keypad-vision-pro.ts new file mode 100644 index 00000000..d96cf2ee --- /dev/null +++ b/src/devices/wo-keypad-vision-pro.ts @@ -0,0 +1,21 @@ +/** + * WoKeypadVisionPro device class for SwitchBot Keypad Vision Pro + * Extends base WoKeypad functionality for lock keypad operations + */ +import type { KeypadStatus } from '../types/device.js' + +import { WoKeypad } from './wo-keypad.js' + +/** + * SwitchBot Keypad Vision Pro device + * @extends WoKeypad + */ +export class WoKeypadVisionPro extends WoKeypad { + /** + * Get keypad status (inherited from WoKeypad) + * @returns Promise resolving to KeypadStatus + */ + async getStatus(): Promise { + return super.getStatus() + } +} diff --git a/src/devices/wo-keypad-vision.ts b/src/devices/wo-keypad-vision.ts new file mode 100644 index 00000000..167e00d9 --- /dev/null +++ b/src/devices/wo-keypad-vision.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-keypad-vision.ts: SwitchBot v4.0.0 - Keypad Vision + */ + +import { WoKeypad } from './wo-keypad.js' + +/** + * Keypad Vision Device + * Uses same logic as Keypad for lock control + */ +export class WoKeypadVision extends WoKeypad {} diff --git a/src/devices/wo-keypad.ts b/src/devices/wo-keypad.ts new file mode 100644 index 00000000..bef77fee --- /dev/null +++ b/src/devices/wo-keypad.ts @@ -0,0 +1,36 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-keypad.ts: SwitchBot v4.0.0 - Keypad Device + */ + +import type { KeypadStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Keypad Device (Touch/Physical) + * Note: Keypad is primarily for lock control, read-only for status + */ +export class WoKeypad extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + lockState: apiStatus.lockState, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-leak.ts b/src/devices/wo-leak.ts new file mode 100644 index 00000000..dfba1086 --- /dev/null +++ b/src/devices/wo-leak.ts @@ -0,0 +1,36 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-leak.ts: SwitchBot v4.0.0 - Water Leak Detector Device + */ + +import type { LeakStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Water Leak Detector Device + */ +export class WoLeak extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + waterLeakDetected: bleData.waterLeakDetected || false, + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + waterLeakDetected: apiStatus.waterLeakDetected || false, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-lock-lite.ts b/src/devices/wo-lock-lite.ts new file mode 100644 index 00000000..12c2cf05 --- /dev/null +++ b/src/devices/wo-lock-lite.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock-lite.ts: SwitchBot v4.0.0 - Smart Lock Lite Device + */ + +import { WoSmartLock } from './wo-lock.js' + +/** + * Smart Lock Lite Device + */ +export class WoSmartLockLite extends WoSmartLock {} diff --git a/src/devices/wo-lock-pro-wifi.ts b/src/devices/wo-lock-pro-wifi.ts new file mode 100644 index 00000000..619c0ef7 --- /dev/null +++ b/src/devices/wo-lock-pro-wifi.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock-pro-wifi.ts: SwitchBot v4.0.0 - Smart Lock Pro WiFi Device + */ + +import { WoSmartLockPro } from './wo-lock-pro.js' + +/** + * Smart Lock Pro WiFi Device (with WiFi connectivity and unlatch support) + */ +export class WoSmartLockProWiFi extends WoSmartLockPro {} diff --git a/src/devices/wo-lock-pro.ts b/src/devices/wo-lock-pro.ts new file mode 100644 index 00000000..02fa7306 --- /dev/null +++ b/src/devices/wo-lock-pro.ts @@ -0,0 +1,150 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock-pro.ts: SwitchBot v4.0.0 - Smart Lock Pro Device + */ + +import type { Buffer } from 'node:buffer' + +import type { LockCommands, LockStatus } from '../types/device.js' + +import { WoSmartLockProCommands } from '../settings.js' +import { SequenceDevice } from './sequence-device.js' + +/** + * Smart Lock Pro Device (with unlatch support) + */ +export class WoSmartLockPro extends SequenceDevice implements LockCommands { + private lockNotificationHandlers = new Set<(payload: Buffer) => void>() + + /** + * Lock the lock + */ + async lock(): Promise { + try { + const status = await this.getStatus() + if (status.lockState === 'locked') { + return true + } + } catch { + // Best effort status check before command + } + + const result = await this.sendCommand( + WoSmartLockProCommands.LOCK, + 'lock', + ) + return result.success + } + + /** + * Unlock the lock + */ + async unlock(): Promise { + try { + const status = await this.getStatus() + if (status.lockState === 'unlocked') { + return true + } + } catch { + // Best effort status check before command + } + + const result = await this.sendCommand( + WoSmartLockProCommands.UNLOCK, + 'unlock', + ) + return result.success + } + + /** + * Unlock without unlatching the door + */ + async unlockWithoutUnlatch(): Promise { + const result = await this.sendCommand( + WoSmartLockProCommands.UNLOCK, + 'unlock', + 'withoutUnlatch', + ) + return result.success + } + + /** + * Unlatch the lock (Lock Pro only) + */ + async unlatch(): Promise { + const result = await this.sendCommand( + WoSmartLockProCommands.UNLATCH, + 'unlock', + ) + return result.success + } + + async getLockInfo(): Promise> { + if (this.hasAPI()) { + const status = await this.getAPIStatus() + return { + lockState: status.lockState, + doorState: status.doorState, + calibrate: status.calibrate, + battery: status.battery, + version: status.version, + } + } + + const ble = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined)) + return { + lockState: ble.lockState, + doorOpen: ble.doorOpen, + calibration: ble.calibration, + battery: ble.battery, + sequenceNumber: ble.sequenceNumber, + } + } + + async onLockNotification(handler: (payload: Buffer) => void): Promise { + if (!this.hasBLE()) { + throw new Error('BLE not available for lock notifications') + } + + const mac = this.info.mac ?? `id:${this.info.bleId}` + await this.bleConnection!.subscribeNotifications(mac, handler) + this.lockNotificationHandlers.add(handler) + } + + offLockNotification(handler: (payload: Buffer) => void): void { + if (!this.hasBLE()) { + return + } + + const mac = this.info.mac ?? `id:${this.info.bleId}` + this.bleConnection?.unsubscribeNotifications(mac, handler) + this.lockNotificationHandlers.delete(handler) + } + + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + lockState: bleData.lockState || 'locked', + doorState: bleData.doorOpen ? 'opened' : 'closed', + calibrated: bleData.calibration, + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + lockState: apiStatus.lockState || 'locked', + doorState: apiStatus.doorState, + calibrated: apiStatus.calibrate, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-lock-vision-pro.ts b/src/devices/wo-lock-vision-pro.ts new file mode 100644 index 00000000..8f9dbfc9 --- /dev/null +++ b/src/devices/wo-lock-vision-pro.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock-vision-pro.ts: SwitchBot v4.0.0 - Smart Lock Vision Pro Device + */ + +import { WoSmartLockPro } from './wo-lock-pro.js' + +/** + * Smart Lock Vision Pro Device (with camera and unlatch support) + */ +export class WoSmartLockVisionPro extends WoSmartLockPro {} diff --git a/src/devices/wo-lock-vision.ts b/src/devices/wo-lock-vision.ts new file mode 100644 index 00000000..d4032539 --- /dev/null +++ b/src/devices/wo-lock-vision.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock-vision.ts: SwitchBot v4.0.0 - Smart Lock Vision Device + */ + +import { WoSmartLock } from './wo-lock.js' + +/** + * Smart Lock Vision Device (with camera) + */ +export class WoSmartLockVision extends WoSmartLock {} diff --git a/src/devices/wo-lock.ts b/src/devices/wo-lock.ts new file mode 100644 index 00000000..3afb33cb --- /dev/null +++ b/src/devices/wo-lock.ts @@ -0,0 +1,126 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-lock.ts: SwitchBot v4.0.0 - Smart Lock Device + */ + +import type { Buffer } from 'node:buffer' + +import type { LockCommands, LockStatus } from '../types/device.js' + +import { WoSmartLockCommands } from '../settings.js' +import { SequenceDevice } from './sequence-device.js' + +/** + * Smart Lock Device + */ +export class WoSmartLock extends SequenceDevice implements LockCommands { + private lockNotificationHandlers = new Set<(payload: Buffer) => void>() + + /** + * Lock the lock + */ + async lock(): Promise { + try { + const status = await this.getStatus() + if (status.lockState === 'locked') { + return true + } + } catch { + // Best effort status check before command + } + + const result = await this.sendCommand( + WoSmartLockCommands.LOCK, + 'lock', + ) + return result.success + } + + /** + * Unlock the lock + */ + async unlock(): Promise { + try { + const status = await this.getStatus() + if (status.lockState === 'unlocked') { + return true + } + } catch { + // Best effort status check before command + } + + const result = await this.sendCommand( + WoSmartLockCommands.UNLOCK, + 'unlock', + ) + return result.success + } + + async getLockInfo(): Promise> { + if (this.hasAPI()) { + const status = await this.getAPIStatus() + return { + lockState: status.lockState, + doorState: status.doorState, + calibrate: status.calibrate, + battery: status.battery, + version: status.version, + } + } + + const ble = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined)) + return { + lockState: ble.lockState, + doorOpen: ble.doorOpen, + calibration: ble.calibration, + battery: ble.battery, + sequenceNumber: ble.sequenceNumber, + } + } + + async onLockNotification(handler: (payload: Buffer) => void): Promise { + if (!this.hasBLE()) { + throw new Error('BLE not available for lock notifications') + } + + const mac = this.info.mac ?? `id:${this.info.bleId}` + await this.bleConnection!.subscribeNotifications(mac, handler) + this.lockNotificationHandlers.add(handler) + } + + offLockNotification(handler: (payload: Buffer) => void): void { + if (!this.hasBLE()) { + return + } + + const mac = this.info.mac ?? `id:${this.info.bleId}` + this.bleConnection?.unsubscribeNotifications(mac, handler) + this.lockNotificationHandlers.delete(handler) + } + + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + lockState: bleData.lockState || 'locked', + calibrated: bleData.calibration, + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + lockState: apiStatus.lockState || 'locked', + doorState: apiStatus.doorState, + calibrated: apiStatus.calibrate, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-pan-tilt-cam-plus-3k.ts b/src/devices/wo-pan-tilt-cam-plus-3k.ts new file mode 100644 index 00000000..93984993 --- /dev/null +++ b/src/devices/wo-pan-tilt-cam-plus-3k.ts @@ -0,0 +1,94 @@ +import type { DeviceStatus } from '../types/index.js' + +import { Buffer } from 'node:buffer' + +import { SwitchBotDevice } from './base.js' + +export class WoPanTiltCamPlus3K extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + // BLE normalization + () => ({ + deviceId: this.info.id, + connectionType: 'ble', + updatedAt: new Date(), + // Add more fields if available from BLE + }), + // API normalization + () => ({ + deviceId: this.info.id, + connectionType: 'api', + updatedAt: new Date(), + // Add more fields if available from API + }), + ) + } + + /** + * Pan the camera (degrees: -180 to 180) + */ + async pan(degrees: number): Promise { + const clamped = Math.max(-180, Math.min(180, degrees)) + // BLE first + if (this.hasBLE()) { + // Example BLE command, update as needed + const command = Buffer.from([0x60, 0x01, clamped & 0xFF]) + const result = await this.sendCommand(command, 'pan', clamped) + if (result.success) { + return true + } + } + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('pan', clamped) + return result.success + } + throw new Error('No connection method available') + } + + /** + * Tilt the camera (degrees: -90 to 90) + */ + async tilt(degrees: number): Promise { + const clamped = Math.max(-90, Math.min(90, degrees)) + // BLE first + if (this.hasBLE()) { + // Example BLE command, update as needed + const command = Buffer.from([0x60, 0x02, clamped & 0xFF]) + const result = await this.sendCommand(command, 'tilt', clamped) + if (result.success) { + return true + } + } + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('tilt', clamped) + return result.success + } + throw new Error('No connection method available') + } + + /** + * Reset the camera position + */ + async reset(): Promise { + // BLE first + if (this.hasBLE()) { + // Example BLE command, update as needed + const command = Buffer.from([0x60, 0x03, 0x00]) + const result = await this.sendCommand(command, 'reset') + if (result.success) { + return true + } + } + // API fallback + if (this.hasAPI()) { + const result = await this.sendAPICommand('reset') + return result.success + } + throw new Error('No connection method available') + } +} diff --git a/src/devices/wo-plug-mini-jp.ts b/src/devices/wo-plug-mini-jp.ts new file mode 100644 index 00000000..af6e9260 --- /dev/null +++ b/src/devices/wo-plug-mini-jp.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-plug-mini-jp.ts: SwitchBot v4.0.0 - Plug Mini (JP) + */ + +import { WoPlugMiniUS } from './wo-plug-mini-us.js' + +/** + * Plug Mini (JP) Device + * Uses same logic as US version + */ +export class WoPlugMiniJP extends WoPlugMiniUS {} diff --git a/src/devices/wo-plug-mini-us.ts b/src/devices/wo-plug-mini-us.ts new file mode 100644 index 00000000..c7f0944d --- /dev/null +++ b/src/devices/wo-plug-mini-us.ts @@ -0,0 +1,76 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-plug-mini-us.ts: SwitchBot v4.0.0 - Plug Mini (US) + */ + +import type { PlugCommands, PlugStatus } from '../types/device.js' + +import { DEVICE_COMMANDS } from '../settings.js' +import { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js' + +/** + * Plug Mini (US) Device + */ +export class WoPlugMiniUS extends DeviceOverrideStateDuringConnection implements PlugCommands { + /** + * Turn on + */ + async turnOn(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.PLUG.TURN_ON, + 'turnOn', + ) + return result.success + } + + /** + * Turn off + */ + async turnOff(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.PLUG.TURN_OFF, + 'turnOff', + ) + return result.success + } + + /** + * Toggle power + */ + async toggle(): Promise { + const result = await this.sendCommand( + DEVICE_COMMANDS.PLUG.TOGGLE, + 'toggle', + ) + return result.success + } + + /** + * Get device status (BLE-first, API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + // BLE normalization + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + voltage: bleData.voltage, + electricCurrent: bleData.electricCurrent, + electricityOfDay: bleData.electricityOfDay, + updatedAt: new Date(), + }), + // API normalization + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + voltage: apiStatus.voltage, + electricCurrent: apiStatus.electricCurrent, + electricityOfDay: apiStatus.electricityOfDay, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-presence.ts b/src/devices/wo-presence.ts new file mode 100644 index 00000000..05e5f22c --- /dev/null +++ b/src/devices/wo-presence.ts @@ -0,0 +1,38 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-presence.ts: SwitchBot v4.0.0 - Motion/Presence Sensor + */ + +import type { MotionStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Motion/Presence Sensor + */ +export class WoPresence extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + moveDetected: bleData.movement || false, + brightness: bleData.lightLevel, + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + moveDetected: apiStatus.moveDetected || false, + brightness: apiStatus.brightness, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-relay-switch-1.ts b/src/devices/wo-relay-switch-1.ts new file mode 100644 index 00000000..adabaec0 --- /dev/null +++ b/src/devices/wo-relay-switch-1.ts @@ -0,0 +1,143 @@ +import type { RelaySwitchCommands, RelaySwitchStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { DEVICE_COMMANDS } from '../settings.js' +import { validateResponseLength } from '../utils/index.js' +import { encryptRelayCommandIfNeeded } from '../utils/relay-encryption.js' +import { SequenceDevice } from './sequence-device.js' + +/** + * Relay Switch 1 Device (1-channel) + */ +export class WoRelaySwitch1 extends SequenceDevice implements RelaySwitchCommands { + /** + * Returns true if this relay switch requires BLE encryption (encryptionKey present) + */ + private needsEncryption(): boolean { + return !!this.info.encryptionKey + } + + /** + * Encrypts a command if encryption is required for this device + */ + protected maybeEncryptCommand(cmd: Buffer | readonly number[]): Buffer { + // Convert readonly arrays to mutable arrays for compatibility + const arr = Buffer.isBuffer(cmd) ? cmd : Buffer.from([...cmd]) + if (!this.needsEncryption()) { + return arr + } + return encryptRelayCommandIfNeeded(arr, this.info.encryptionKey!, this.info.encryptionIV) + } + + /** + * Verifies the BLE encryption key by attempting a status read with encryption. + * Throws an error if the key is invalid or the device rejects the command. + */ + async verifyEncryptionKey(): Promise { + if (!this.needsEncryption()) { + throw new Error('No encryptionKey set for this device') + } + try { + // Try to get status with encryption; if the key is wrong, device will reject or return invalid data + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.COMMON.POWER_ON]) + const result = await this.sendCommand(command, 'verifyEncryptionKey') + if (!result.success) { + throw new Error('Encryption key verification failed: device did not accept encrypted command') + } + return true + } catch (err: any) { + throw new Error(`Encryption key verification failed: ${err?.message || err}`) + } + } + + private parseRelayPowerResponse(buffer: Buffer): { + voltage?: number + electricCurrent?: number + electricityOfDay?: number + } { + validateResponseLength(buffer, 11, 'WoRelaySwitch1:parseRelayPowerResponse') + + // Best-effort parsing aligned with relay basic-info responses. + const voltageRaw = buffer.readUInt16BE(5) + const currentRaw = buffer.readUInt16BE(7) + const energyRaw = buffer.readUInt16BE(9) + + return { + voltage: voltageRaw / 10, + electricCurrent: currentRaw / 100, + electricityOfDay: energyRaw / 100, + } + } + + private async getRelayPowerMonitoring(): Promise<{ + voltage?: number + electricCurrent?: number + electricityOfDay?: number + }> { + if (!this.hasBLE()) { + return {} + } + + const result = await this.sendBLECommand(DEVICE_COMMANDS.RELAY.GET_BASIC_INFO) + if (!result.success || !result.data || !Buffer.isBuffer(result.data)) { + return {} + } + + return this.parseRelayPowerResponse(result.data) + } + + /** + * Turn on + */ + async turnOn(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.COMMON.POWER_ON]) + const result = await this.sendCommand(command, 'turnOn') + return result.success + } + + /** + * Turn off + */ + async turnOff(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.COMMON.POWER_OFF]) + const result = await this.sendCommand(command, 'turnOff') + return result.success + } + + /** + * Toggle power + */ + async toggle(): Promise { + const command = this.maybeEncryptCommand([...DEVICE_COMMANDS.PLUG.TOGGLE]) + const result = await this.sendCommand(command, 'toggle') + return result.success + } + + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + power: bleData.state ? 'on' : 'off', + voltage: bleData.voltage, + electricCurrent: bleData.electricCurrent, + electricityOfDay: bleData.electricityOfDay, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + power: apiStatus.power || 'off', + voltage: apiStatus.voltage, + electricCurrent: apiStatus.electricCurrent, + electricityOfDay: apiStatus.electricityOfDay, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-relay-switch-1pm.ts b/src/devices/wo-relay-switch-1pm.ts new file mode 100644 index 00000000..77ee8703 --- /dev/null +++ b/src/devices/wo-relay-switch-1pm.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-relay-switch-1pm.ts: SwitchBot v4.0.0 - Relay Switch 1PM Device + */ + +import { WoRelaySwitch1 } from './wo-relay-switch-1.js' + +/** + * Relay Switch 1PM Device (1-channel with power monitoring) + * Uses same logic as Relay Switch 1 + */ +export class WoRelaySwitch1PM extends WoRelaySwitch1 {} diff --git a/src/devices/wo-relay-switch-2pm.ts b/src/devices/wo-relay-switch-2pm.ts new file mode 100644 index 00000000..5d961684 --- /dev/null +++ b/src/devices/wo-relay-switch-2pm.ts @@ -0,0 +1,42 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-relay-switch-2pm.ts: SwitchBot v4.0.0 - Relay Switch 2PM Device + */ + +import type { RelaySwitchChannelCommands, RelaySwitchStatus } from '../types/device.js' + +import { DEVICE_COMMANDS } from '../settings.js' +import { WoRelaySwitch1 } from './wo-relay-switch-1.js' + +/** + * Relay Switch 2PM Device (2-channel with power monitoring) + * Extends Relay Switch 1 with channel-specific control + */ +export class WoRelaySwitch2PM extends WoRelaySwitch1 implements RelaySwitchChannelCommands { + /** + * Set channel 1 state + */ + async setChannel1(state: boolean): Promise { + const raw = state ? DEVICE_COMMANDS.RELAY.CHANNEL1_ON : DEVICE_COMMANDS.RELAY.CHANNEL1_OFF + const command = this.maybeEncryptCommand([...raw]) + const result = await this.sendCommand(command, `setChannel1:${state}`) + return result.success + } + + /** + * Set channel 2 state + */ + async setChannel2(state: boolean): Promise { + const raw = state ? DEVICE_COMMANDS.RELAY.CHANNEL2_ON : DEVICE_COMMANDS.RELAY.CHANNEL2_OFF + const command = this.maybeEncryptCommand([...raw]) + const result = await this.sendCommand(command, `setChannel2:${state}`) + return result.success + } + + /** + * Get device status (inherited, same as 1PM) + */ + async getStatus(): Promise { + return super.getStatus() + } +} diff --git a/src/devices/wo-remote-with-screen.ts b/src/devices/wo-remote-with-screen.ts new file mode 100644 index 00000000..809716d5 --- /dev/null +++ b/src/devices/wo-remote-with-screen.ts @@ -0,0 +1,27 @@ +import type { DeviceStatus } from '../types/index.js' + +import { SwitchBotDevice } from './base.js' + +export class WoRemoteWithScreen extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + updatedAt: new Date(), + battery: bleData.battery, + version: bleData.version, + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + updatedAt: new Date(), + battery: apiStatus.battery, + version: apiStatus.version, + }), + ) + } +} diff --git a/src/devices/wo-remote.ts b/src/devices/wo-remote.ts new file mode 100644 index 00000000..e88353f5 --- /dev/null +++ b/src/devices/wo-remote.ts @@ -0,0 +1,35 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-remote.ts: SwitchBot v4.0.0 - Remote Device + */ + +import type { RemoteStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Remote Device (IR remote control) + * Note: Remote is read-only for battery status + */ +export class WoRemote extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-rgbic-bulb.ts b/src/devices/wo-rgbic-bulb.ts new file mode 100644 index 00000000..6afce37e --- /dev/null +++ b/src/devices/wo-rgbic-bulb.ts @@ -0,0 +1,103 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-rgbic-bulb.ts: SwitchBot v4.0.0 - RGBIC Color Bulb with Segmented Control + */ + +import type { RGBICBulbCommands, RGBICBulbStatus } from '../types/device.js' + +import { clamp } from '../utils/index.js' +import { WoBulb } from './wo-bulb.js' + +/** + * RGBIC Bulb Device with segmented/multi-zone color control + * Supports individual LED segment control for addressable RGB+IC strips + */ +export class WoRGBICBulb extends WoBulb implements RGBICBulbCommands { + private static readonly RGBIC_EFFECTS: Record = { + // Standard effects (compatible with WoBulb) + christmas: 0x00, + candle: 0x01, + halloween: 0x02, + sunset: 0x03, + party: 0x04, + reading: 0x05, + rainbow: 0x06, + forest: 0x07, + ocean: 0x08, + spring: 0x09, + summer: 0x0A, + autumn: 0x0B, + winter: 0x0C, + aurora: 0x0D, + meteor: 0x0E, + firework: 0x0F, + breathe: 0x10, + pulse: 0x11, + flicker: 0x12, + pet: 0x13, + // RGBIC-specific effects + segment_cycle: 0x20, + segment_wave: 0x21, + segment_chase: 0x22, + segment_strobe: 0x23, + segment_twinkle: 0x24, + } + + /** + * Set color for individual LED segment + * @param segmentId - Segment identifier (0-based index) + * @param red - Red value (0-255) + * @param green - Green value (0-255) + * @param blue - Blue value (0-255) + */ + async setSegmentColor(segmentId: number, red: number, green: number, blue: number): Promise { + const segId = clamp(segmentId, 0, 255) + const r = clamp(red, 0, 255) + const g = clamp(green, 0, 255) + const b = clamp(blue, 0, 255) + + // Command format for segment color: varies by device + // Using extended command format: 0x57 0x0F 0x47 0x01 0x13 SEG_ID R G B + const bleCommand = [0x57, 0x0F, 0x47, 0x01, 0x13, segId, r, g, b] + + const result = await this.sendCommand( + bleCommand, + 'setSegmentColor', + `seg${segId}:${r}:${g}:${b}`, + ) + return result.success + } + + /** + * Set effect for individual LED segment + * @param segmentId - Segment identifier (0-based index) + * @param effectName - Effect name from RGBIC_EFFECTS + * @param speed - Effect speed (1-100, default: 50) + */ + async setSegmentEffect(segmentId: number, effectName: string, speed = 50): Promise { + const effectId = WoRGBICBulb.RGBIC_EFFECTS[effectName.toLowerCase()] + if (effectId === undefined) { + throw new Error(`Unsupported RGBIC effect: ${effectName}`) + } + + const segId = clamp(segmentId, 0, 255) + const effectSpeed = clamp(speed, 1, 100) + + // Command format for segment effect: 0x57 0x0F 0x47 0x01 0x14 SEG_ID EFFECT_ID SPEED + const bleCommand = [0x57, 0x0F, 0x47, 0x01, 0x14, segId, effectId, effectSpeed] + + const result = await this.sendCommand( + bleCommand, + 'setSegmentEffect', + `seg${segId}:${effectName}:${effectSpeed}`, + ) + return result.success + } + + /** + * Get device status (inherited from WoBulb, centralized fallback) + */ + async getStatus(): Promise { + return super.getStatus() + } +} diff --git a/src/devices/wo-rgbic-neon-wire-rope-light.ts b/src/devices/wo-rgbic-neon-wire-rope-light.ts new file mode 100644 index 00000000..cfedb573 --- /dev/null +++ b/src/devices/wo-rgbic-neon-wire-rope-light.ts @@ -0,0 +1,124 @@ +import type { RGBICBulbStatus } from '../types/device.js' + +import { Buffer } from 'node:buffer' + +import { SwitchBotDevice } from './base.js' + +export class WoRGBICNeonWireRopeLight extends SwitchBotDevice { + /** + * Get device status (BLE-first/API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + updatedAt: new Date(), + power: bleData.state ? 'on' : 'off', + brightness: bleData.brightness, + colorTemperature: bleData.colorTemperature, + color: bleData.red !== undefined ? { r: bleData.red, g: bleData.green, b: bleData.blue } : undefined, + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + updatedAt: new Date(), + power: apiStatus.power, + brightness: apiStatus.brightness, + colorTemperature: apiStatus.colorTemperature, + color: apiStatus.color, + }), + ) + } + + /** + * Turn on the neon wire rope light + */ + async turnOn(): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x01]) + const result = await this.sendCommand(command, 'turnOn') + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOn') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Turn off the neon wire rope light + */ + async turnOff(): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x01, 0x02]) + const result = await this.sendCommand(command, 'turnOff') + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('turnOff') + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set brightness (1-100) + */ + async setBrightness(level: number): Promise { + const clamped = Math.max(1, Math.min(100, level)) + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x02, clamped]) + const result = await this.sendCommand(command, 'setBrightness', clamped) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setBrightness', clamped) + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set color (RGB) + */ + async setColor(red: number, green: number, blue: number): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x03, red, green, blue]) + const result = await this.sendCommand(command, 'setColor', { red, green, blue }) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setColor', { red, green, blue }) + return result.success + } + throw new Error('No connection method available') + } + + /** + * Set color temperature (Kelvin) + */ + async setColorTemperature(temperature: number): Promise { + if (this.hasBLE()) { + const command = Buffer.from([0x57, 0x04, temperature & 0xFF, (temperature >> 8) & 0xFF]) + const result = await this.sendCommand(command, 'setColorTemperature', temperature) + if (result.success) { + return true + } + } + if (this.hasAPI()) { + const result = await this.sendAPICommand('setColorTemperature', temperature) + return result.success + } + throw new Error('No connection method available') + } +} diff --git a/src/devices/wo-rgbicww-floor-lamp.ts b/src/devices/wo-rgbicww-floor-lamp.ts new file mode 100644 index 00000000..8916cefc --- /dev/null +++ b/src/devices/wo-rgbicww-floor-lamp.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-rgbicww-floor-lamp.ts: SwitchBot v4.0.0 - RGBICWW Floor Lamp + */ + +import { WoRGBICBulb } from './wo-rgbic-bulb.js' + +/** + * RGBICWW Floor Lamp Device + * Uses same logic as RGBIC Bulb with segmented control + */ +export class WoRGBICWWFloorLamp extends WoRGBICBulb {} diff --git a/src/devices/wo-rgbicww-strip-light.ts b/src/devices/wo-rgbicww-strip-light.ts new file mode 100644 index 00000000..2c0d4bbc --- /dev/null +++ b/src/devices/wo-rgbicww-strip-light.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-rgbicww-strip-light.ts: SwitchBot v4.0.0 - RGBICWW Strip Light + */ + +import { WoRGBICBulb } from './wo-rgbic-bulb.js' + +/** + * RGBICWW Strip Light Device + * Uses same logic as RGBIC Bulb with segmented control + */ +export class WoRGBICWWStripLight extends WoRGBICBulb {} diff --git a/src/devices/wo-roller-shade.ts b/src/devices/wo-roller-shade.ts new file mode 100644 index 00000000..059af760 --- /dev/null +++ b/src/devices/wo-roller-shade.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-roller-shade.ts: SwitchBot v4.0.0 - Roller Shade + */ + +import { WoCurtain } from './wo-curtain.js' + +/** + * Roller Shade Device + * Uses same logic as Curtain (motorized window covering) + */ +export class WoRollerShade extends WoCurtain {} diff --git a/src/devices/wo-sensor-th-plus.ts b/src/devices/wo-sensor-th-plus.ts new file mode 100644 index 00000000..5eacf0ad --- /dev/null +++ b/src/devices/wo-sensor-th-plus.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-sensor-th-plus.ts: SwitchBot v4.0.0 - Meter Plus + */ + +import { WoSensorTH } from './wo-sensor-th.js' + +/** + * Meter Plus (Temperature/Humidity Sensor with screen) + * Uses same logic as standard Meter + */ +export class WoSensorTHPlus extends WoSensorTH {} diff --git a/src/devices/wo-sensor-th-pro-co2.ts b/src/devices/wo-sensor-th-pro-co2.ts new file mode 100644 index 00000000..e39be5b4 --- /dev/null +++ b/src/devices/wo-sensor-th-pro-co2.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-sensor-th-pro-co2.ts: SwitchBot v4.0.0 - Meter Pro CO2 + */ + +import { WoSensorTH } from './wo-sensor-th.js' + +/** + * Meter Pro CO2 (Temperature/Humidity/CO2 Sensor) + * Use same logic as standard Meter (CO2 data available in extended status) + */ +export class WoSensorTHProCO2 extends WoSensorTH {} diff --git a/src/devices/wo-sensor-th-pro.ts b/src/devices/wo-sensor-th-pro.ts new file mode 100644 index 00000000..cd100837 --- /dev/null +++ b/src/devices/wo-sensor-th-pro.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-sensor-th-pro.ts: SwitchBot v4.0.0 - Meter Pro + */ + +import { WoSensorTH } from './wo-sensor-th.js' + +/** + * Meter Pro (Advanced Temperature/Humidity Sensor) + * Uses same logic as standard Meter + */ +export class WoSensorTHPro extends WoSensorTH {} diff --git a/src/devices/wo-sensor-th.ts b/src/devices/wo-sensor-th.ts new file mode 100644 index 00000000..b8ffe288 --- /dev/null +++ b/src/devices/wo-sensor-th.ts @@ -0,0 +1,39 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-sensor-th.ts: SwitchBot v4.0.0 - Meter (Temp/Humidity Sensor) + */ + +import type { MeterStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +/** + * Meter (Temperature/Humidity Sensor) + */ +export class WoSensorTH extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + temperature: bleData.temperature || 0, + humidity: bleData.humidity || 0, + temperatureScale: bleData.fahrenheit ? 'f' : 'c', + battery: bleData.battery, + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + temperature: apiStatus.temperature || 0, + humidity: apiStatus.humidity || 0, + battery: apiStatus.battery, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } +} diff --git a/src/devices/wo-smart-thermostat-radiator.ts b/src/devices/wo-smart-thermostat-radiator.ts new file mode 100644 index 00000000..7d12a402 --- /dev/null +++ b/src/devices/wo-smart-thermostat-radiator.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-smart-thermostat-radiator.ts: SwitchBot v4.0.0 - Smart Thermostat Radiator Device + */ + +import { WoAirPurifier } from './wo-air-purifier.js' + +/** + * Smart Thermostat Radiator Device + * Reuses climate control behavior for power, mode, and speed-level style control. + */ +export class WoSmartThermostatRadiator extends WoAirPurifier {} diff --git a/src/devices/wo-strip-light-3.ts b/src/devices/wo-strip-light-3.ts new file mode 100644 index 00000000..5edb652e --- /dev/null +++ b/src/devices/wo-strip-light-3.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-strip-light-3.ts: SwitchBot v4.0.0 - Strip Light 3 + */ + +import { WoBulb } from './wo-bulb.js' + +/** + * Strip Light 3 Device + * Uses same logic as Color Bulb + */ +export class WoStripLight3 extends WoBulb {} diff --git a/src/devices/wo-strip.ts b/src/devices/wo-strip.ts new file mode 100644 index 00000000..925b3854 --- /dev/null +++ b/src/devices/wo-strip.ts @@ -0,0 +1,12 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-strip.ts: SwitchBot v4.0.0 - Strip Light + */ + +import { WoBulb } from './wo-bulb.js' + +/** + * Strip Light Device + * Uses same logic as Color Bulb + */ +export class WoStrip extends WoBulb {} diff --git a/src/devices/wo-vacuum-k10-plus.ts b/src/devices/wo-vacuum-k10-plus.ts new file mode 100644 index 00000000..f2aa3f7a --- /dev/null +++ b/src/devices/wo-vacuum-k10-plus.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-k10-plus.ts: SwitchBot v4.0.0 - K10+ Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner K10+ + */ +export class WoVacuumK10Plus extends WoVacuum {} diff --git a/src/devices/wo-vacuum-k10-pro-combo.ts b/src/devices/wo-vacuum-k10-pro-combo.ts new file mode 100644 index 00000000..6dc63a3b --- /dev/null +++ b/src/devices/wo-vacuum-k10-pro-combo.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-k10-pro-combo.ts: SwitchBot v4.0.0 - K10+ Pro Combo Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner K10+ Pro Combo + */ +export class WoVacuumK10ProCombo extends WoVacuum {} diff --git a/src/devices/wo-vacuum-k10-pro.ts b/src/devices/wo-vacuum-k10-pro.ts new file mode 100644 index 00000000..15ebeb21 --- /dev/null +++ b/src/devices/wo-vacuum-k10-pro.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-k10-pro.ts: SwitchBot v4.0.0 - K10+ Pro Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner K10+ Pro + */ +export class WoVacuumK10Pro extends WoVacuum {} diff --git a/src/devices/wo-vacuum-k11-plus.ts b/src/devices/wo-vacuum-k11-plus.ts new file mode 100644 index 00000000..de81bcb2 --- /dev/null +++ b/src/devices/wo-vacuum-k11-plus.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-k11-plus.ts: SwitchBot v4.0.0 - K11+ Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner K11+ + */ +export class WoVacuumK11Plus extends WoVacuum {} diff --git a/src/devices/wo-vacuum-k20.ts b/src/devices/wo-vacuum-k20.ts new file mode 100644 index 00000000..91b9833b --- /dev/null +++ b/src/devices/wo-vacuum-k20.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-k20.ts: SwitchBot v4.0.0 - K20 Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner K20 + */ +export class WoVacuumK20 extends WoVacuum {} diff --git a/src/devices/wo-vacuum-s10.ts b/src/devices/wo-vacuum-s10.ts new file mode 100644 index 00000000..e702bb42 --- /dev/null +++ b/src/devices/wo-vacuum-s10.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-s10.ts: SwitchBot v4.0.0 - S10 Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner S10 + */ +export class WoVacuumS10 extends WoVacuum {} diff --git a/src/devices/wo-vacuum-s20.ts b/src/devices/wo-vacuum-s20.ts new file mode 100644 index 00000000..e221fb9f --- /dev/null +++ b/src/devices/wo-vacuum-s20.ts @@ -0,0 +1,11 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum-s20.ts: SwitchBot v4.0.0 - S20 Vacuum Device + */ + +import { WoVacuum } from './wo-vacuum.js' + +/** + * Robot Vacuum Cleaner S20 + */ +export class WoVacuumS20 extends WoVacuum {} diff --git a/src/devices/wo-vacuum.ts b/src/devices/wo-vacuum.ts new file mode 100644 index 00000000..59785ff0 --- /dev/null +++ b/src/devices/wo-vacuum.ts @@ -0,0 +1,162 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * devices/wo-vacuum.ts: SwitchBot v4.0.0 - Vacuum Device + */ + +import type { VacuumCommands, VacuumStatus } from '../types/device.js' + +import { DEVICE_COMMANDS } from '../settings.js' +import { SequenceDevice } from './sequence-device.js' + +/** + * Vacuum Device + */ +export class WoVacuum extends SequenceDevice implements VacuumCommands { + /** + * Start cleaning (BLE-first, API-fallback) + */ + async cleanUp(protocolVersion: number): Promise { + // Validate protocol version first + if (protocolVersion !== 1 && protocolVersion !== 2) { + throw new Error(`Unsupported vacuum protocol version: ${protocolVersion}`) + } + // Try BLE first + if (this.hasBLE()) { + try { + const command = this.getCommandForProtocol(DEVICE_COMMANDS.VACUUM.CLEAN_UP, protocolVersion) + const result = await this.sendCommand(command, 'start', { protocolVersion }) + if (result.success) { + return true + } + } catch (err) { + this.logger.warn('BLE cleanUp failed, falling back to API', err) + } + } + // Fallback to API + if (this.hasAPI()) { + const apiResult = await this.sendAPICommand('start', { protocolVersion }) + return apiResult.success + } + throw new Error('No connection method available for cleanUp') + } + + /** + * Return to dock (BLE-first, API-fallback) + */ + async returnToDock(protocolVersion: number): Promise { + // Validate protocol version first + if (protocolVersion !== 1 && protocolVersion !== 2) { + throw new Error(`Unsupported vacuum protocol version: ${protocolVersion}`) + } + // Try BLE first + if (this.hasBLE()) { + try { + const command = this.getCommandForProtocol(DEVICE_COMMANDS.VACUUM.RETURN_TO_DOCK, protocolVersion) + const result = await this.sendCommand(command, 'dock', { protocolVersion }) + if (result.success) { + return true + } + } catch (err) { + this.logger.warn('BLE returnToDock failed, falling back to API', err) + } + } + // Fallback to API + if (this.hasAPI()) { + const apiResult = await this.sendAPICommand('dock', { protocolVersion }) + return apiResult.success + } + throw new Error('No connection method available for returnToDock') + } + + /** + * Return advertised battery value + */ + getBattery(): number | undefined { + const data = this.getAdvertisementStatusData() + return this.asNumber(data.battery) + } + + /** + * Return advertised work status value + */ + getWorkStatus(): number | undefined { + const data = this.getAdvertisementStatusData() + return this.asNumber(data.workStatus ?? data.work_status) + } + + /** + * Return advertised dustbin bound state + */ + getDustbinBoundStatus(): boolean | undefined { + const data = this.getAdvertisementStatusData() + return this.asBoolean(data.dustbinBound ?? data.dustbin_bound) + } + + /** + * Return advertised dustbin connected state + */ + getDustbinConnectedStatus(): boolean | undefined { + const data = this.getAdvertisementStatusData() + return this.asBoolean(data.dustbinConnected ?? data.dusbin_connected) + } + + /** + * Return advertised network connected state + */ + getNetworkConnectedStatus(): boolean | undefined { + const data = this.getAdvertisementStatusData() + return this.asBoolean(data.networkConnected ?? data.network_connected) + } + + /** + * Get device status (BLE-first/API-fallback, centralized) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + battery: this.asNumber(bleData.battery), + workStatus: this.asNumber(bleData.workStatus ?? bleData.work_status), + dustbinBound: this.asBoolean(bleData.dustbinBound ?? bleData.dustbin_bound), + dustbinConnected: this.asBoolean(bleData.dustbinConnected ?? bleData.dusbin_connected), + networkConnected: this.asBoolean(bleData.networkConnected ?? bleData.network_connected), + updatedAt: new Date(), + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + battery: apiStatus.battery, + workStatus: apiStatus.workStatus ?? apiStatus.work_status, + dustbinBound: apiStatus.dustbinBound ?? apiStatus.dustbin_bound, + dustbinConnected: apiStatus.dustbinConnected ?? apiStatus.dusbin_connected, + networkConnected: apiStatus.networkConnected ?? apiStatus.network_connected, + version: apiStatus.version, + updatedAt: new Date(), + }), + ) + } + + private getCommandForProtocol( + commands: { 1: readonly number[], 2: readonly number[] }, + protocolVersion: number, + ): readonly number[] { + if (protocolVersion !== 1 && protocolVersion !== 2) { + throw new Error(`Unsupported vacuum protocol version: ${protocolVersion}`) + } + + return commands[protocolVersion as 1 | 2] + } + + private getAdvertisementStatusData(): Record { + return this.normalizeBLEStatusData(undefined) + } + + private asNumber(value: unknown): number | undefined { + return typeof value === 'number' ? value : undefined + } + + private asBoolean(value: unknown): boolean | undefined { + return typeof value === 'boolean' ? value : undefined + } +} diff --git a/src/devices/wo-water-detector.ts b/src/devices/wo-water-detector.ts new file mode 100644 index 00000000..6ca37a64 --- /dev/null +++ b/src/devices/wo-water-detector.ts @@ -0,0 +1,25 @@ +import type { LeakStatus } from '../types/device.js' + +import { SwitchBotDevice } from './base.js' + +export class WoWaterDetector extends SwitchBotDevice { + /** + * Get device status (BLE-first, API-fallback) + */ + async getStatus(): Promise { + return this.getStatusWithFallback( + bleData => ({ + deviceId: this.info.id, + connectionType: 'ble', + updatedAt: new Date(), + waterLeakDetected: !!bleData.waterLeakDetected, + }), + apiStatus => ({ + deviceId: this.info.id, + connectionType: 'api', + updatedAt: new Date(), + waterLeakDetected: !!apiStatus.waterLeakDetected, + }), + ) + } +} diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 00000000..e6c7c93d --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,132 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * errors.ts: SwitchBot v4.0.0 - Custom Error Classes + */ + +/** + * Base error class for SwitchBot errors + */ +export class SwitchBotError extends Error { + constructor(message: string, public readonly code?: string) { + super(message) + this.name = 'SwitchBotError' + } +} + +/** + * Error thrown for generic BLE operation failures + */ +export class SwitchbotOperationError extends SwitchBotError { + constructor(message: string, public readonly originalError?: Error) { + super(message, 'BLE_OPERATION_FAILED') + this.name = 'SwitchbotOperationError' + } +} + +/** + * Error thrown for BLE authentication failures (e.g., encryption key invalid) + */ +export class SwitchbotAuthenticationError extends SwitchBotError { + constructor(message: string, public readonly originalError?: Error) { + super(message, 'BLE_AUTH_FAILED') + this.name = 'SwitchbotAuthenticationError' + } +} + +/** + * Error thrown when a required BLE characteristic is missing + */ +export class CharacteristicMissingError extends SwitchBotError { + constructor(characteristic: string) { + super(`BLE characteristic missing: ${characteristic}`, 'BLE_CHARACTERISTIC_MISSING') + this.name = 'CharacteristicMissingError' + } +} + +/** + * Error thrown when BLE is not available or supported + */ +export class BLENotAvailableError extends SwitchBotError { + constructor(message = 'BLE not available on this platform or device') { + super(message, 'BLE_NOT_AVAILABLE') + this.name = 'BLENotAvailableError' + } +} + +/** + * Error thrown when API is not available or credentials are missing + */ +export class APINotAvailableError extends SwitchBotError { + constructor(message = 'API not available or credentials not provided') { + super(message, 'API_NOT_AVAILABLE') + this.name = 'APINotAvailableError' + } +} + +/** + * Error thrown when a device is not found + */ +export class DeviceNotFoundError extends SwitchBotError { + constructor(deviceId: string) { + super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND') + this.name = 'DeviceNotFoundError' + } +} + +/** + * Error thrown when a command fails + */ +export class CommandFailedError extends SwitchBotError { + constructor( + message: string, + public readonly connectionType?: 'ble' | 'api', + public readonly originalError?: Error, + ) { + super(message, 'COMMAND_FAILED') + this.name = 'CommandFailedError' + } +} + +/** + * Error thrown when a connection timeout occurs + */ +export class ConnectionTimeoutError extends SwitchBotError { + constructor(message = 'Connection timeout', public readonly timeoutMs?: number) { + super(message, 'CONNECTION_TIMEOUT') + this.name = 'ConnectionTimeoutError' + } +} + +/** + * Error thrown when device discovery fails + */ +export class DiscoveryError extends SwitchBotError { + constructor(message: string, public readonly originalError?: Error) { + super(message, 'DISCOVERY_ERROR') + this.name = 'DiscoveryError' + } +} + +/** + * Error thrown when API request fails + */ +export class APIError extends SwitchBotError { + constructor( + message: string, + public readonly statusCode?: number, + public readonly statusMessage?: string, + ) { + super(message, 'API_ERROR') + this.name = 'APIError' + } +} + +/** + * Error thrown when invalid parameters are provided + */ +export class ValidationError extends SwitchBotError { + constructor(message: string, public readonly parameter?: string) { + super(message, 'VALIDATION_ERROR') + this.name = 'ValidationError' + } +} diff --git a/src/index.test.ts b/src/index.test.ts deleted file mode 100644 index f27be3ae..00000000 --- a/src/index.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import * as index from './index.js' - -describe('index module exports', () => { - it('should export switchbot-ble', () => { - expect(index.SwitchBotBLE).toBeDefined() - }) - - it('should export switchbot-openapi', () => { - expect(index.SwitchBotOpenAPI).toBeDefined() - }) - - it('should export SwitchbotDevice', () => { - expect(index.SwitchbotDevice).toBeDefined() - }) -}) diff --git a/src/index.ts b/src/index.ts index 0e675c89..155cd93f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,174 @@ -/* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. * - * index.ts: Switchbot BLE API registration. + * index.ts: SwitchBot v4.0.0 - Hybrid BLE/OpenAPI Main Exports */ -// Primary module exports -export * from './device.js' -export { ParameterChecker, parameterChecker } from './parameter-checker.js' + +// Main classes (alphabetically by module path) +export { OpenAPIClient } from './api.js' +export { BLEConnection, BLEScanner } from './ble.js' +export { DeviceManager, SwitchBotDevice } from './devices/base.js' +export { DeviceOverrideStateDuringConnection } from './devices/device-override-state-during-connection.js' +export { + WoAIHub, + WoAirPurifier, + WoAirPurifierPM25, + WoAirPurifierTable, + WoArtFrame, + WoBlindTilt, + WoBulb, + WoCandleWarmerLamp, + WoCeilingLight, + WoCirculatorFan, + WoClimatePanel, + WoContact, + WoCurtain, + WoFloorLamp, + WoGarageDoorOpener, + WoHand, + WoHub2, + WoHub3, + WoHubMiniMatter, + WoHumi, + WoHumi2, + WoIOSensorTH, + WoKeypad, + WoKeypadVision, + WoKeypadVisionPro, + WoLeak, + WoPanTiltCamPlus3K, + WoPlugMiniJP, + WoPlugMiniUS, + WoPresence, + WoRelaySwitch1, + WoRelaySwitch1PM, + WoRelaySwitch2PM, + WoRemote, + WoRemoteWithScreen, + WoRGBICBulb, + WoRGBICNeonWireRopeLight, + WoRGBICWWFloorLamp, + WoRGBICWWStripLight, + WoRollerShade, + WoSensorTH, + WoSensorTHPlus, + WoSensorTHPro, + WoSensorTHProCO2, + WoSmartLock, + WoSmartLockLite, + WoSmartLockPro, + WoSmartLockProWiFi, + WoSmartLockVision, + WoSmartLockVisionPro, + WoSmartThermostatRadiator, + WoStrip, + WoStripLight3, + WoVacuum, + WoVacuumK10Plus, + WoVacuumK10Pro, + WoVacuumK10ProCombo, + WoVacuumK11Plus, + WoVacuumK20, + WoVacuumS10, + WoVacuumS20, + WoWaterDetector, +} from './devices/index.js' +export { SequenceDevice } from './devices/sequence-device.js' +export { + APIError, + APINotAvailableError, + BLENotAvailableError, + CommandFailedError, + ConnectionTimeoutError, + DeviceNotFoundError, + DiscoveryError, + SwitchBotError, + ValidationError, +} from './errors.js' export { updateBaseURL, urls } from './settings.js' -export * from './switchbot-ble.js' -export * from './switchbot-openapi.js' +export { SwitchBot } from './switchbot.js' -// Type definitions -export * from './types/ble.js' -export * from './types/openapi.js' +// Type exports (alphabetically by module path, then by export name) +export type { + APICommandRequest, + APICommandResponse, + APIDevice, + APIDeviceStatus, + APIErrorResponse, + APIResponse, + DeviceListResponse, + PhysicalDeviceType, + SceneListResponse, + VirtualDeviceType, + WebhookConfig, + WebhookDetails, + WebhookQueryResponse, + WebhookSetupResponse, +} from './types/api.js' +export type { + AirPurifierServiceData, + BLEAdvertisement, + BLEScanOptions, + BLEServiceData, + BlindTiltServiceData, + BotServiceData, + BulbServiceData, + CeilingLightServiceData, + ContactServiceData, + CurtainServiceData, + HubServiceData, + HumidifierServiceData, + LeakServiceData, + LockServiceData, + MeterServiceData, + MotionServiceData, + PlugServiceData, + PresenceServiceData, + RelaySwitchServiceData, + StripServiceData, + SwitchBotBLEModel, + SwitchBotBLEModelName, +} from './types/ble.js' +export type { + AirPurifierCommands, + AirPurifierStatus, + BlindTiltCommands, + BlindTiltStatus, + BotCommands, + BotStatus, + BulbCommands, + BulbStatus, + CeilingLightCommands, + CeilingLightStatus, + ContactStatus, + CurtainCommands, + CurtainExtendedInfo, + CurtainStatus, + HubStatus, + HumidifierCommands, + HumidifierStatus, + KeypadStatus, + LeakStatus, + LockCommands, + LockStatus, + MeterStatus, + MotionStatus, + PlugCommands, + PlugStatus, + PresenceStatus, + RelaySwitchCommands, + RelaySwitchStatus, + RemoteStatus, + StripCommands, + StripStatus, + VacuumCommands, + VacuumStatus, +} from './types/device.js' +export type { + CommandResult, + ConnectionType, + DeviceInfo, + DeviceStatus, + DiscoveryOptions, + LogLevel, + SwitchBotConfig, +} from './types/index.js' diff --git a/src/parameter-checker.test.ts b/src/parameter-checker.test.ts deleted file mode 100644 index 8226739b..00000000 --- a/src/parameter-checker.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { Rule } from './device.js' - -import { describe, expect, it } from 'vitest' - -import { ParameterChecker } from './parameter-checker.js' - -describe('parameterChecker', () => { - it('should pass with empty rules and no required object', async () => { - const checker = new ParameterChecker() - const result = await checker.check({}, {}, false) - expect(result).toBe(true) - expect(checker.error).toBeNull() - }) - - it('should fail when required object is missing', async () => { - const checker = new ParameterChecker() - const result = await checker.check(undefined as any, {}, true) - expect(result).toBe(false) - expect(checker.error?.code).toBe('MISSING_REQUIRED') - }) - - it('should fail when required field is missing', async () => { - const checker = new ParameterChecker() - const rules: Record = { - name: { type: 'string', required: true }, - } - const result = await checker.check({}, rules) - expect(result).toBe(false) - expect(checker.error?.code).toBe('MISSING_REQUIRED') - }) - - it('should fail on type mismatch for integer', async () => { - const checker = new ParameterChecker() - const rules: Record = { - age: { type: 'integer', required: true }, - } - const result = await checker.check({ age: 25.5 }, rules) - expect(result).toBe(false) - expect(checker.error?.code).toBe('TYPE_INVALID') - }) - - it('should enforce float min and max', async () => { - const checker = new ParameterChecker() - const rules: Record = { - temperature: { type: 'float', min: 0, max: 100 }, - } - let result = await checker.check({ temperature: -5 }, rules) - expect(result).toBe(false) - expect(checker.error?.code).toBe('VALUE_UNDERFLOW') - - result = await checker.check({ temperature: 150 }, rules) - expect(result).toBe(false) - expect(checker.error?.code).toBe('VALUE_OVERFLOW') - }) - - it('should ignore extra parameters', async () => { - const checker = new ParameterChecker() - const rules: Record = { - id: { type: 'integer' }, - } - const result = await checker.check({ id: 1, extra: 'ignored' }, rules) - expect(result).toBe(true) - expect(checker.error).toBeNull() - }) -}) diff --git a/src/parameter-checker.ts b/src/parameter-checker.ts deleted file mode 100644 index 72ee998c..00000000 --- a/src/parameter-checker.ts +++ /dev/null @@ -1,310 +0,0 @@ -import type { ErrorObject, Rule } from './device.js' - -import { Buffer } from 'node:buffer' -/* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. - * - * parameter-checker.ts: Switchbot BLE API registration. - */ -import { EventEmitter } from 'node:events' - -export class ParameterChecker extends EventEmitter { - private _error: ErrorObject | null = null - // Mapping of type names to checker methods - private readonly typeCheckers: Record Promise> = { - float: this.isFloat.bind(this), - integer: this.isInteger.bind(this), - boolean: this.isBoolean.bind(this), - array: this.isArray.bind(this), - object: this.isObject.bind(this), - string: this.isString.bind(this), - } - - /** - * Emits a log event with the specified log level and message. - * - * @param level - The severity level of the log (e.g., 'info', 'warn', 'error'). - * @param message - The log message to be emitted. - */ - private emitLog(level: string, message: string): void { - this.emit('log', { level, message }) - } - - /** - * Gets the current error object. - * - * @returns {ErrorObject | null} - The current error object or null if no error. - */ - get error(): ErrorObject | null { - return this._error - } - - /** - * Checks if the value is specified (not undefined). - * - * @param {unknown} value - The value to check. - * @returns {boolean} - True if the value is specified, false otherwise. - */ - isSpecified(value: unknown): boolean { - return value !== undefined - } - - /** - * Checks if the specified object contains valid values based on the provided rules. - * - * @param {Record} obj - Object including parameters you want to check. - * @param {Record} rules - Object including rules for the parameters. - * @param {boolean} [required] - Flag whether the `obj` is required or not. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async check(obj: Record, rules: Record, required: boolean = false): Promise { - this._error = null - this.emitLog('debug', `Using rules: ${JSON.stringify(rules)}`) - - if (required && !this.isSpecified(obj)) { - this._error = { code: 'MISSING_REQUIRED', message: 'The first argument is missing.' } - return false - } - - if (!required && !obj) { - return true - } - - if (!this.isObject(obj, {})) { - this._error = { code: 'MISSING_REQUIRED', message: 'The first argument is missing.' } - return false - } - - for (const [name, rule] of Object.entries(rules)) { - const value = obj[name] - - if (!this.isSpecified(value)) { - if (rule.required) { - this._error = { code: 'MISSING_REQUIRED', message: `The \`${name}\` is required.` } - return false - } - continue - } - - const checker = rule.type && this.typeCheckers[rule.type] - if (checker) { - if (!(await checker(value, rule, name))) { - return false - } - } else { - // Unknown type specified in rule - this.emitLog('error', `Unknown type "${rule.type}" in rule for parameter "${name}"`) - this._error = { code: 'TYPE_UNKNOWN', message: `Unknown type "${rule.type}" for parameter "${name}"` } - return false - } - } - // Warn about extra parameters not defined in rules - const extra = Object.keys(obj).filter(key => !(key in rules)) - if (extra.length) { - this.emitLog('warn', `Ignoring extra parameters: ${extra.join(', ')}`) - } - - this.emitLog('debug', 'All checks passed.') - return true - } - - /** - * Checks if the value is a float. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isFloat(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (typeof value !== 'number') { - this._error = { code: 'TYPE_INVALID', message: `The \`${name}\` must be a number (integer or float).` } - return false - } - - if (typeof rule.min === 'number' && value < rule.min) { - this._error = { code: 'VALUE_UNDERFLOW', message: `The \`${name}\` must be greater than or equal to ${rule.min}.` } - return false - } - - if (typeof rule.max === 'number' && value > rule.max) { - this._error = { code: 'VALUE_OVERFLOW', message: `The \`${name}\` must be less than or equal to ${rule.max}.` } - return false - } - - if (Array.isArray(rule.enum) && !rule.enum.includes(value)) { - this._error = { code: 'ENUM_UNMATCH', message: `The \`${name}\` must be any one of ${JSON.stringify(rule.enum)}.` } - return false - } - - return true - } - - /** - * Checks if the value is an integer. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isInteger(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (Number.isInteger(value)) { - return true - } - - this._error = { code: 'TYPE_INVALID', message: `The \`${name}\` must be an integer.` } - return false - } - - /** - * Checks if the value is a boolean. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isBoolean(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (typeof value !== 'boolean') { - this._error = { code: 'TYPE_INVALID', message: `The \`${name}\` must be boolean.` } - return false - } - - return true - } - - /** - * Checks if the value is an object. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isObject(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - this._error = { code: 'TYPE_INVALID', message: `The \`${name}\` must be an object.` } - return false - } - - return true - } - - /** - * Checks if the value is an array. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isArray(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (!Array.isArray(value)) { - this._error = { code: 'TYPE_INVALID', message: 'The value must be an array.' } - return false - } - - if (typeof rule.min === 'number' && value.length < rule.min) { - this._error = { code: 'LENGTH_UNDERFLOW', message: `The number of elements in the \`${name}\` must be greater than or equal to ${rule.min}.` } - return false - } - - if (typeof rule.max === 'number' && value.length > rule.max) { - this._error = { code: 'LENGTH_OVERFLOW', message: `The number of elements in the \`${name}\` must be less than or equal to ${rule.max}.` } - return false - } - - return true - } - - /** - * Checks if the value is a string. - * - * @param {unknown} value - The value to check. - * @param {Rule} rule - The rule object containing validation criteria. - * @param {string} [name] - The parameter name. - * @returns {Promise} - Resolves to true if the value is valid, false otherwise. - */ - async isString(value: unknown, rule: Rule, name: string = 'value'): Promise { - this._error = null - - if (!rule.required && !this.isSpecified(value)) { - return true - } - - if (typeof value !== 'string') { - this._error = { code: 'TYPE_INVALID', message: 'The value must be a string.' } - return false - } - - if (typeof rule.min === 'number' && value.length < rule.min) { - this._error = { code: 'LENGTH_UNDERFLOW', message: `The number of characters in the \`${name}\` must be greater than or equal to ${rule.min}.` } - return false - } - - if (typeof rule.max === 'number' && value.length > rule.max) { - this._error = { code: 'LENGTH_OVERFLOW', message: `The number of characters in the \`${name}\` must be less than or equal to ${rule.max}.` } - return false - } - - if (typeof rule.minBytes === 'number') { - const blen = Buffer.from(value, 'utf8').length - if (blen < rule.minBytes) { - this._error = { code: 'LENGTH_UNDERFLOW', message: `The byte length of the \`${name}\` (${blen} bytes) must be greater than or equal to ${rule.minBytes} bytes.` } - return false - } - } - - if (typeof rule.maxBytes === 'number') { - const blen = Buffer.from(value, 'utf8').length - if (blen > rule.maxBytes) { - this._error = { code: 'LENGTH_OVERFLOW', message: `The byte length of the \`${name}\` (${blen} bytes) must be less than or equal to ${rule.maxBytes} bytes.` } - return false - } - } - - if (rule.pattern instanceof RegExp && !rule.pattern.test(value)) { - this._error = { code: 'PATTERN_UNMATCH', message: `The \`${name}\` does not conform with the pattern.` } - return false - } - - if (Array.isArray(rule.enum) && !rule.enum.includes(value)) { - this._error = { code: 'ENUM_UNMATCH', message: `The \`${name}\` must be any one of ${JSON.stringify(rule.enum)}.` } - return false - } - - return true - } -} - -export const parameterChecker = new ParameterChecker() diff --git a/src/settings.test.ts b/src/settings.test.ts deleted file mode 100644 index 7dcf29cc..00000000 --- a/src/settings.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import { - CHAR_UUID_DEVICE, - CHAR_UUID_NOTIFY, - CHAR_UUID_WRITE, - COMMAND_TIMEOUT_MSEC, - READ_TIMEOUT_MSEC, - SERV_UUID_PRIMARY, - updateBaseURL, - urls, - WoSmartLockCommands, - WoSmartLockProCommands, - WRITE_TIMEOUT_MSEC, -} from './settings.js' - -describe('switchBot API Settings', () => { - it('should have correct Devices URL', () => { - expect(urls.devicesURL).toBe('https://api.switch-bot.com/v1.1/devices') - }) - - it('should have correct setupWebhook URL', () => { - expect(urls.setupWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/setupWebhook') - }) - - it('should have correct queryWebhook URL', () => { - expect(urls.queryWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/queryWebhook') - }) - - it('should have correct updateWebhook URL', () => { - expect(urls.updateWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/updateWebhook') - }) - - it('should have correct deleteWebhook URL', () => { - expect(urls.deleteWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/deleteWebhook') - }) - - it('should have correct BLE API constants', () => { - expect(SERV_UUID_PRIMARY).toBe('cba20d00224d11e69fb80002a5d5c51b') - expect(CHAR_UUID_WRITE).toBe('cba20002224d11e69fb80002a5d5c51b') - expect(CHAR_UUID_NOTIFY).toBe('cba20003224d11e69fb80002a5d5c51b') - expect(CHAR_UUID_DEVICE).toBe('2a00') - }) - - it('should have correct timeout constants', () => { - expect(READ_TIMEOUT_MSEC).toBe(3000) - expect(WRITE_TIMEOUT_MSEC).toBe(3000) - expect(COMMAND_TIMEOUT_MSEC).toBe(3000) - }) - - it('should have correct WoSmartLockProCommands', () => { - expect(WoSmartLockProCommands.GET_CKIV).toBe('570f2103') - expect(WoSmartLockProCommands.LOCK_INFO).toBe('570f4f8102') - expect(WoSmartLockProCommands.UNLOCK).toBe('570f4e0101000080') - expect(WoSmartLockProCommands.UNLOCK_NO_UNLATCH).toBe('570f4e01010000a0') - expect(WoSmartLockProCommands.LOCK).toBe('570f4e0101000000') - expect(WoSmartLockProCommands.ENABLE_NOTIFICATIONS).toBe('570e01001e00008101') - expect(WoSmartLockProCommands.DISABLE_NOTIFICATIONS).toBe('570e00') - }) - - it('should have correct WoSmartLockCommands', () => { - expect(WoSmartLockCommands.GET_CKIV).toBe('570f2103') - expect(WoSmartLockCommands.LOCK_INFO).toBe('570f4f8101') - expect(WoSmartLockCommands.UNLOCK).toBe('570f4e01011080') - expect(WoSmartLockCommands.UNLOCK_NO_UNLATCH).toBe('570f4e010110a0') - expect(WoSmartLockCommands.LOCK).toBe('570f4e01011000') - expect(WoSmartLockCommands.ENABLE_NOTIFICATIONS).toBe('570e01001e00008101') - expect(WoSmartLockCommands.DISABLE_NOTIFICATIONS).toBe('570e00') - }) - - it('should update URLs when baseURL is changed', () => { - const original = urls.baseURL - const custom = 'https://custom.api' - updateBaseURL(custom) - expect(urls.devicesURL).toBe(`${custom}/v1.1/devices`) - expect(urls.setupWebhook).toBe(`${custom}/v1.1/webhook/setupWebhook`) - expect(urls.queryWebhook).toBe(`${custom}/v1.1/webhook/queryWebhook`) - expect(urls.updateWebhook).toBe(`${custom}/v1.1/webhook/updateWebhook`) - expect(urls.deleteWebhook).toBe(`${custom}/v1.1/webhook/deleteWebhook`) - // restore original baseURL - updateBaseURL(original) - }) -}) diff --git a/src/settings.ts b/src/settings.ts index cee8b42f..fb16e202 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,86 +1,344 @@ /** - * Switchbot BLE API registration settings. + * Passive polling interval (24 hours) + */ +// ms +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. * - * © 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * settings.ts: SwitchBot v4.0.0 - Configuration and Constants */ -let baseURL = 'https://api.switch-bot.com' -// API version used for endpoint paths -const API_VERSION = '/v1.1' +import process from 'node:process' + +export const PASSIVE_POLL_INTERVAL = 60 * 60 * 24 * 1000 + +/** + * OpenAPI Configuration + */ +export const DEFAULT_BASE_URL = 'https://api.switch-bot.com' +export const API_VERSION = 'v1.1' -// URLs are generated dynamically via getters below +export const urls: { + base: string + devices: string + scenes: string + webhook: string +} = { + base: DEFAULT_BASE_URL, + devices: `${DEFAULT_BASE_URL}/${API_VERSION}/devices`, + scenes: `${DEFAULT_BASE_URL}/${API_VERSION}/scenes`, + webhook: `${DEFAULT_BASE_URL}/${API_VERSION}/webhook`, +} /** - * Updates the base URL for the SwitchBot API endpoints. - * @param {string} newBaseURL - The new base URL to use. + * Update the base URL for all API endpoints + * @param newBaseURL - The new base URL to use */ export function updateBaseURL(newBaseURL: string): void { - baseURL = newBaseURL + urls.base = newBaseURL + urls.devices = `${newBaseURL}/${API_VERSION}/devices` + urls.scenes = `${newBaseURL}/${API_VERSION}/scenes` + urls.webhook = `${newBaseURL}/${API_VERSION}/webhook` } -export const urls = { - get baseURL() { - return baseURL +/** + * BLE Configuration + */ +export const BLE_SERVICE_UUID = 'cba20d00224d11e69fb80002a5d5c51b' +export const BLE_WRITE_CHARACTERISTIC_UUID = 'cba20002224d11e69fb80002a5d5c51b' +export const BLE_NOTIFY_CHARACTERISTIC_UUID = 'cba20003224d11e69fb80002a5d5c51b' + +// Alternative UUIDs for specific devices +export const SERV_UUID_PRIMARY = 'cba20d00-224d-11e6-9fb8-0002a5d5c51b' +export const CHAR_UUID_WRITE = 'cba20002-224d-11e6-9fb8-0002a5d5c51b' +export const CHAR_UUID_NOTIFY = 'cba20003-224d-11e6-9fb8-0002a5d5c51b' +export const CHAR_UUID_DEVICE = 'cba20d00-224d-11e6-9fb8-0002a5d5c51b' + +/** + * BLE Timeouts (in milliseconds) + */ +export const BLE_SCAN_TIMEOUT = 10000 +export const BLE_CONNECT_TIMEOUT = 10000 +export const BLE_COMMAND_TIMEOUT = 5000 +export const READ_TIMEOUT_MSEC = 10000 +export const WRITE_TIMEOUT_MSEC = 10000 + +/** + * Device Command Constants + */ +export const DEVICE_COMMANDS = { + // Bot (WoHand) + BOT: { + PRESS: [0x57, 0x01, 0x00] as const, + TURN_ON: [0x57, 0x01, 0x01] as const, + TURN_OFF: [0x57, 0x01, 0x02] as const, + DOWN: [0x57, 0x01, 0x01] as const, + UP: [0x57, 0x01, 0x02] as const, + SET_MODE: [0x57, 0x0F, 0x47, 0x01] as const, + SET_LONG_PRESS: [0x57, 0x0F, 0x47, 0x03] as const, }, - get devicesURL() { - return `${baseURL}${API_VERSION}/devices` + + // Curtain (WoCurtain) + CURTAIN: { + OPEN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00] as const, + CLOSE: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64] as const, + PAUSE: [0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF] as const, + POSITION: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF] as const, // Add position byte + EXTENDED_INFO: [0x57, 0x0F, 0x46, 0x01] as const, // Get device chain and grouped status }, - get setupWebhook() { - return `${baseURL}${API_VERSION}/webhook/setupWebhook` + + // Blind Tilt + BLIND_TILT: { + OPEN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x32] as const, + CLOSE_UP: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64] as const, + CLOSE_DOWN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00] as const, + PAUSE: [0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF] as const, }, - get queryWebhook() { - return `${baseURL}${API_VERSION}/webhook/queryWebhook` + + // Bulb (WoBulb) + BULB: { + BASE: [0x57, 0x0F, 0x47, 0x01] as const, + READ_STATE: [0x57, 0x0F, 0x48, 0x01] as const, + TURN_ON: [0x01, 0x01] as const, + TURN_OFF: [0x01, 0x02] as const, + SET_BRIGHTNESS: [0x02, 0x14] as const, // Add brightness byte + SET_COLOR_TEMP: [0x02, 0x17] as const, // Add temp bytes + SET_RGB: [0x02, 0x12] as const, // Add RGB bytes + SET_EFFECT: [0x03] as const, }, - get updateWebhook() { - return `${baseURL}${API_VERSION}/webhook/updateWebhook` + + // Humidifier + HUMIDIFIER: { + HEADER: '5701' as const, + TURN_ON: '570101' as const, + TURN_OFF: '570102' as const, + INCREASE: '570103' as const, + DECREASE: '570104' as const, + SET_AUTO_MODE: '570105' as const, + SET_MANUAL_MODE: '570106' as const, }, - get deleteWebhook() { - return `${baseURL}${API_VERSION}/webhook/deleteWebhook` + + // Air Purifier + AIR_PURIFIER: { + TURN_ON: [0x57, 0x01, 0x01] as const, + TURN_OFF: [0x57, 0x01, 0x02] as const, + SET_MODE: [0x57, 0x02] as const, // Add mode byte + SET_SPEED: [0x57, 0x03] as const, // Add speed byte + }, + + // Vacuum + VACUUM: { + CLEAN_UP: { + 1: [0x57, 0x0F, 0x5A, 0x00, 0xFF, 0xFF, 0x70, 0x01] as const, + 2: [0x5A, 0x40, 0x01, 0x01, 0x01, 0x01, 0x26] as const, + }, + RETURN_TO_DOCK: { + 1: [0x57, 0x0F, 0x5A, 0x00, 0xFF, 0xFF, 0x70, 0x02] as const, + 2: [0x5A, 0x40, 0x01, 0x01, 0x01, 0x02, 0x25] as const, + }, }, -} + + // Plug + PLUG: { + TURN_ON: [0x57, 0x0F, 0x50, 0x01, 0x01] as const, + TURN_OFF: [0x57, 0x0F, 0x50, 0x01, 0x02] as const, + TOGGLE: [0x57, 0x0F, 0x50, 0x01, 0x00] as const, + }, + + RELAY: { + GET_BASIC_INFO: [0x57, 0x02] as const, + CHANNEL1_ON: [0x57, 0x0F, 0x50, 0x01, 0x01] as const, + CHANNEL1_OFF: [0x57, 0x0F, 0x50, 0x01, 0x02] as const, + CHANNEL2_ON: [0x57, 0x0F, 0x50, 0x02, 0x01] as const, + CHANNEL2_OFF: [0x57, 0x0F, 0x50, 0x02, 0x02] as const, + }, + + // Common commands + COMMON: { + POWER_ON: [0x57, 0x01, 0x01] as const, + POWER_OFF: [0x57, 0x01, 0x02] as const, + }, +} as const /** - * constants used to access SwitchBot BLE API + * Lock Command Constants (WoSmartLock) */ -export const SERV_UUID_PRIMARY = 'cba20d00224d11e69fb80002a5d5c51b' -export const CHAR_UUID_WRITE = 'cba20002224d11e69fb80002a5d5c51b' -export const CHAR_UUID_NOTIFY = 'cba20003224d11e69fb80002a5d5c51b' -export const CHAR_UUID_DEVICE = '2a00' - -export const READ_TIMEOUT_MSEC = 3000 -export const WRITE_TIMEOUT_MSEC = 3000 -export const COMMAND_TIMEOUT_MSEC = 3000 - -export const DEFAULT_DISCOVERY_DURATION = 5000 -export const PRIMARY_SERVICE_UUID_LIST = [] - -export enum WoSmartLockProCommands { - GET_CKIV = '570f2103', - LOCK_INFO = '570f4f8102', - UNLOCK = '570f4e0101000080', - UNLOCK_NO_UNLATCH = '570f4e01010000a0', - LOCK = '570f4e0101000000', - ENABLE_NOTIFICATIONS = '570e01001e00008101', - DISABLE_NOTIFICATIONS = '570e00', -} +export const WoSmartLockCommands = { + LOCK: [0x57, 0x0F, 0x4E, 0x01, 0x00] as const, + UNLOCK: [0x57, 0x0F, 0x4E, 0x01, 0x01] as const, +} as const -export enum WoSmartLockCommands { - GET_CKIV = '570f2103', - LOCK_INFO = '570f4f8101', - UNLOCK = '570f4e01011080', - UNLOCK_NO_UNLATCH = '570f4e010110a0', - LOCK = '570f4e01011000', - ENABLE_NOTIFICATIONS = '570e01001e00008101', - DISABLE_NOTIFICATIONS = '570e00', -} +/** + * Lock Pro Command Constants (WoSmartLockPro) + */ +export const WoSmartLockProCommands = { + LOCK: [0x57, 0x0F, 0x4F, 0x01, 0x00] as const, + UNLOCK: [0x57, 0x0F, 0x4F, 0x01, 0x01] as const, + UNLATCH: [0x57, 0x0F, 0x4F, 0x01, 0x02] as const, +} as const -// Lock Ultra uses the same command structure as Lock Pro (AES/IV based). -export enum WoSmartLockUltraCommands { - GET_CKIV = '570f2103', - LOCK_INFO = '570f4f8102', - UNLOCK = '570f4e0101000080', - UNLOCK_NO_UNLATCH = '570f4e01010000a0', - LOCK = '570f4e0101000000', - ENABLE_NOTIFICATIONS = '570e01001e00008101', - DISABLE_NOTIFICATIONS = '570e00', -} +/** + * Device Model to Type Mapping + */ +export const DEVICE_MODEL_MAP: Record = { + 'H': 'Bot', + 'c': 'Curtain', + '{': 'Curtain3', + 'g': 'Plug', + 'j': 'Plug Mini (US)', + 'T': 'Meter', + 'i': 'Meter Plus', + 'o': 'Lock', + '\x11': 'Lock Pro', + 'k': 'Keypad', + '\x0B': 'Keypad Touch', + 's': 'Motion Sensor', + 'd': 'Contact Sensor', + 'q': 'Ceiling Light', + 'r': 'Ceiling Light Pro', + 'p': 'Strip Light', + 'u': 'Color Bulb', + '\x0A': 'Robot Vacuum Cleaner S1', + '\x0C': 'Robot Vacuum Cleaner S1 Plus', + '\x0F': 'Robot Vacuum Cleaner K10 Plus', + 'e': 'Humidifier', + '\x07': 'Humidifier 2', + 'x': 'Blind Tilt', + '\x01': 'Hub 2', + '\x02': 'Hub 3', + '\x05': 'Remote', + '\x04': 'Battery Circulator Fan', + '\x08': 'Air Purifier', + '\x09': 'Air Purifier Table', + 'y': 'Water Leak Detector', + '\x06': 'Presence Sensor', + '\x0D': 'Relay Switch 1PM', + '\x0E': 'Relay Switch 1', + '\x10': 'K10+ Pro Combo', + 'w': 'Meter Pro (CO2)', + 'n': 'Outdoor Meter', +} as const + +/** + * Device Type to Class Name Mapping + */ +export const DEVICE_CLASS_MAP: Record = { + 'Bot': 'WoHand', + 'Curtain': 'WoCurtain', + 'Curtain3': 'WoCurtain', + 'Roller Shade': 'WoRollerShade', + 'SwitchBot Roller Shade': 'WoRollerShade', + 'Plug': 'WoPlugMiniUS', + 'WoPlugUS': 'WoPlugMiniUS', + 'Plug Mini (US)': 'WoPlugMiniUS', + 'Plug Mini (JP)': 'WoPlugMiniJP', + 'Plug Mini (EU)': 'WoPlugMiniEU', + 'Meter': 'WoSensorTH', + 'Meter Plus': 'WoSensorTHPlus', + 'Meter Pro': 'WoSensorTHPro', + 'Meter Pro (CO2)': 'WoSensorTHProCO2', + 'Outdoor Meter': 'WoIOSensorTH', + 'Lock': 'WoSmartLock', + 'Lock Lite': 'WoSmartLockLite', + 'Lock Pro': 'WoSmartLockPro', + 'Lock Pro WiFi': 'WoSmartLockProWiFi', + 'Lock Vision': 'WoSmartLockVision', + 'Lock Vision Pro': 'WoSmartLockVisionPro', + 'Keypad': 'WoKeypad', + 'Keypad Touch': 'WoKeypad', + 'Keypad Vision': 'WoKeypadVision', + 'SwitchBot Keypad Vision': 'WoKeypadVision', + 'Keypad Vision Pro': 'WoKeypadVisionPro', + 'SwitchBot Keypad Vision Pro': 'WoKeypadVisionPro', + 'Motion Sensor': 'WoPresence', + 'Contact Sensor': 'WoContact', + 'Ceiling Light': 'WoCeilingLight', + 'Ceiling Light Pro': 'WoCeilingLight', + 'Strip Light': 'WoStrip', + 'Strip Light 3': 'WoStripLight3', + 'SwitchBot Strip Light 3': 'WoStripLight3', + 'Color Bulb': 'WoBulb', + 'Floor Lamp': 'WoFloorLamp', + 'SwitchBot Floor Lamp': 'WoFloorLamp', + 'RGBICWW Strip Light': 'WoRGBICWWStripLight', + 'SwitchBot RGBICWW Strip Light': 'WoRGBICWWStripLight', + 'RGBICWW Floor Lamp': 'WoRGBICWWFloorLamp', + 'SwitchBot RGBICWW Floor Lamp': 'WoRGBICWWFloorLamp', + 'Art Frame': 'WoArtFrame', + 'SwitchBot Art Frame': 'WoArtFrame', + 'Robot Vacuum Cleaner S1': 'WoVacuumS10', + 'Robot Vacuum Cleaner S1 Plus': 'WoVacuumS20', + 'Robot Vacuum Cleaner K10 Plus': 'WoVacuumK10Plus', + 'Robot Vacuum Cleaner K10+': 'WoVacuumK10Plus', + 'Robot Vacuum Cleaner K10+ Pro': 'WoVacuumK10Pro', + 'Robot Vacuum Cleaner K11+': 'WoVacuumK11Plus', + 'Robot Vacuum Cleaner K20': 'WoVacuumK20', + 'Robot Vacuum Cleaner S10': 'WoVacuumS10', + 'Robot Vacuum Cleaner S20': 'WoVacuumS20', + 'Humidifier': 'WoHumi', + 'Humidifier 2': 'WoHumi2', + 'Evaporative Humidifier': 'WoHumi2', + 'Evaporative Humidifier (Auto-refill)': 'WoHumi2', + 'SwitchBot Evaporative Humidifier (Auto-refill)': 'WoHumi2', + 'Blind Tilt': 'WoBlindTilt', + 'Hub 2': 'WoHub2', + 'Hub 3': 'WoHub3', + 'SwitchBot Hub 3': 'WoHub3', + 'Hub Mini': 'WoHub2', + 'HubMini Matter': 'WoHubMiniMatter', + 'SwitchBot HubMini Matter': 'WoHubMiniMatter', + 'Hub Plus': 'WoHub2', + 'Remote': 'WoRemote', + 'Battery Circulator Fan': 'WoCirculatorFan', + 'Circulator Fan': 'WoCirculatorFan', + 'USB Circulator Fan': 'WoCirculatorFan', + 'Smart Thermostat Radiator': 'WoSmartThermostatRadiator', + 'Thermostat Radiator': 'WoSmartThermostatRadiator', + 'Radiator Thermostat': 'WoSmartThermostatRadiator', + 'Climate Panel': 'WoClimatePanel', + 'Smart Climate Panel': 'WoClimatePanel', + 'Air Purifier': 'WoAirPurifier', + 'Air Purifier Table': 'WoAirPurifierTable', + 'Water Leak Detector': 'WoLeak', + 'Presence Sensor': 'WoPresence', + 'Relay Switch 1PM': 'WoRelaySwitch1PM', + 'Relay Switch 1': 'WoRelaySwitch1', + 'Relay Switch 2PM': 'WoRelaySwitch2PM', + 'Garage Door Opener': 'WoGarageDoorOpener', + 'K10+ Pro Combo': 'WoVacuumK10ProCombo', + 'Robot Vacuum Cleaner K10+ Pro Combo': 'WoVacuumK10ProCombo', + // User-reported unknown device types + 'Air Purifier PM2.5': 'WoAirPurifierPM25', + 'K10+': 'WoVacuumK10Plus', + 'RGBIC Neon Wire Rope Light': 'WoRGBICNeonWireRopeLight', + 'Candle Warmer Lamp': 'WoCandleWarmerLamp', + 'Pan/Tilt Cam Plus 3K': 'WoPanTiltCamPlus3K', + 'remote with screen': 'WoRemoteWithScreen', + 'AI Hub': 'WoAIHub', + 'Water Detector': 'WoWaterDetector', +} as const + +/** + * Default configuration values + */ +export const DEFAULTS = { + logLevel: 2, // WARN + scanTimeout: BLE_SCAN_TIMEOUT, + connectTimeout: BLE_CONNECT_TIMEOUT, + commandTimeout: BLE_COMMAND_TIMEOUT, + enableBLE: true, + enableFallback: true, + baseURL: DEFAULT_BASE_URL, + enableConnectionIntelligence: true, + enableCircuitBreaker: true, + enableRetry: true, + maxRetryAttempts: 3, + retryInitialDelayMs: 100, + retryMaxDelayMs: 5000, +} as const + +/** + * Platform detection + */ +export const IS_LINUX = process.platform === 'linux' +export const IS_MACOS = process.platform === 'darwin' +export const BLE_SUPPORTED = IS_LINUX || IS_MACOS diff --git a/src/switchbot-ble.test.ts b/src/switchbot-ble.test.ts deleted file mode 100644 index 7d1bd2c9..00000000 --- a/src/switchbot-ble.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import { LogLevel, SwitchBotBLE } from './switchbot-ble' - -describe('switchBotBLE', () => { - describe('constructor', () => { - it('should create an instance without parameters', () => { - const switchbot = new SwitchBotBLE() - expect(switchbot).toBeInstanceOf(SwitchBotBLE) - expect(switchbot.nobleInitialized).toBeInstanceOf(Promise) - }) - - it('should create an instance with parameters', () => { - const params = { duration: 5000 } - const switchbot = new SwitchBotBLE(params) - expect(switchbot).toBeInstanceOf(SwitchBotBLE) - expect(switchbot.nobleInitialized).toBeInstanceOf(Promise) - }) - }) - - it('should emit log events asynchronously', async () => { - const sw = new SwitchBotBLE() - // Listen for a single 'log' event - const eventPromise = new Promise<{ level: string, message: string }>((resolve) => { - sw.once('log', (event) => { - resolve(event) - }) - }) - sw.log(LogLevel.INFO, 'test message') - const event = (await eventPromise) as { level: string, message: string } - expect(event.level).toBe('info') - expect(event.message).toBe('test message') - expect(event.message).toBe('test message') - }) -}) diff --git a/src/switchbot-ble.ts b/src/switchbot-ble.ts deleted file mode 100644 index 61358712..00000000 --- a/src/switchbot-ble.ts +++ /dev/null @@ -1,352 +0,0 @@ -/* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. - * - * switchbot.ts: Switchbot BLE API registration. - */ -import type { ad, NobleTypes, onadvertisement, ondiscover, Params, Rule } from './device.js' - -import { EventEmitter } from 'node:events' - -import { Advertising, LogLevel, SwitchBotBLEModel, SwitchbotDevice, WoBlindTilt, WoBulb, WoCeilingLight, WoContact, WoCurtain, WoHand, WoHub2, WoHumi, WoHumi2, WoIOSensorTH, WoKeypad, WoLeak, WoPlugMiniEU, WoPlugMiniJP, WoPlugMiniUS, WoPresence, WoRelaySwitch1, WoRelaySwitch1PM, WoRemote, WoSensorTH, WoSensorTHPlus, WoSensorTHPro, WoSensorTHProCO2, WoSmartLock, WoSmartLockPro, WoSmartLockUltra, WoStrip } from './device.js' -import { parameterChecker } from './parameter-checker.js' -import { DEFAULT_DISCOVERY_DURATION, PRIMARY_SERVICE_UUID_LIST } from './settings.js' - -/** - * SwitchBotBLE class to interact with SwitchBot devices. - */ -export class SwitchBotBLE extends EventEmitter { - public nobleInitialized: Promise - public noble: any - ondiscover?: ondiscover - onadvertisement?: onadvertisement - - /** - * Constructor - * - * @param {Params} [params] - Optional parameters - */ - constructor(params?: Params) { - super() - this.nobleInitialized = this.initialize(params) - } - - /** - * Emits a log event with the specified log level and message. - * - * @param level - The severity level of the log (e.g., 'info', 'warn', 'error'). - * @param message - The log message to be emitted. - */ - /** - * Emits a log event with a defined LogLevel. - */ - public log(level: LogLevel, message: string): void { - // Emit log events asynchronously with level and message as separate args - setTimeout(() => this.emit('log', { level, message }), 0) - } - - /** - * Initializes the noble object. - * - * @param {Params} [params] - Optional parameters - * @returns {Promise} - Resolves when initialization is complete - */ - private async initialize(params?: Params): Promise { - try { - if (params && params.noble) { - this.noble = params.noble - } else { - this.noble = (await import('@stoprocent/noble')).default - } - - try { - await this.noble.waitForPoweredOnAsync() - this.log(LogLevel.DEBUG, 'Noble powered on') - } catch (e: any) { - this.log(LogLevel.ERROR, `Failed waiting for powered on: ${JSON.stringify(e.message ?? e)}`) - } - } catch (e: any) { - this.log(LogLevel.ERROR, `Failed to import noble: ${JSON.stringify(e.message ?? e)}`) - } - } - - /** - * Validates the parameters. - * - * @param {Params} params - The parameters to validate. - * @param {Record} schema - The schema to validate against. - * @returns {Promise} - Resolves if parameters are valid, otherwise throws an error. - */ - public async validate(params: Params, schema: Record): Promise { - const valid = parameterChecker.check(params as Record, schema as Record, false) - if (!valid) { - this.log(LogLevel.ERROR, `parameterChecker: ${JSON.stringify(parameterChecker.error!.message)}`) - throw new Error(parameterChecker.error!.message) - } - } - - /** - * Discovers Switchbot devices with enhanced error handling and logging. - * @param params The discovery parameters. - * @returns A Promise that resolves with an array of discovered Switchbot devices. - */ - public async discover(params: Params = {}): Promise { - await this.initialize(params) - await this.validate(params, { - duration: { required: false, type: 'integer', min: 1, max: 60000 }, - model: { required: false, type: 'string', enum: Object.values(SwitchBotBLEModel) }, - id: { required: false, type: 'string', min: 12, max: 17 }, - quick: { required: false, type: 'boolean' }, - }) - - if (!this.noble) { - throw new Error('Noble BLE library failed to initialize properly') - } - - const p = { - duration: params.duration ?? DEFAULT_DISCOVERY_DURATION, - model: params.model as SwitchBotBLEModel ?? '', - id: params.id ?? '', - quick: !!params.quick, - } - - this.log(LogLevel.DEBUG, `Starting discovery with parameters: ${JSON.stringify(p)}`) - - const peripherals: Record = {} - let timer: NodeJS.Timeout - let isDiscoveryActive = true - - const finishDiscovery = async () => { - if (!isDiscoveryActive) { - return Object.values(peripherals) - } - - isDiscoveryActive = false - if (timer) { - clearTimeout(timer) - } - if (this.noble) { - this.noble.removeAllListeners('discover') - try { - await this.noble.stopScanningAsync() - this.log(LogLevel.DEBUG, 'Successfully stopped scanning for SwitchBot BLE devices') - } catch (e: any) { - this.log(LogLevel.ERROR, `Failed to stop scanning: ${JSON.stringify(e.message ?? e)}`) - } - } - - const devices = Object.values(peripherals) - const deviceCount = devices.length - this.log( - deviceCount > 0 ? LogLevel.INFO : LogLevel.WARN, - `Discovery completed. Found ${deviceCount} device${deviceCount !== 1 ? 's' : ''}`, - ) - - return devices - } - - return new Promise((resolve, reject) => { - this.noble.on('discover', async (peripheral: NobleTypes['peripheral']) => { - try { - const device = await this.createDevice(peripheral, p.id, p.model as SwitchBotBLEModel) - if (!device) { - return - } - - if (peripherals[device.id!]) { - this.log(LogLevel.DEBUG, `Device ${device.id} already discovered, skipping duplicate`) - return - } - - peripherals[device.id!] = device - this.log(LogLevel.DEBUG, `Discovered device: ${device.friendlyName} (${device.id}) at ${device.address}`) - - if (this.ondiscover) { - try { - await this.ondiscover(device) - } catch (e: any) { - this.log(LogLevel.ERROR, `Error in ondiscover callback: ${e.message ?? e}`) - } - } - - if (p.quick) { - this.log(LogLevel.DEBUG, 'Quick discovery mode: stopping after first device found') - resolve(await finishDiscovery()) - } - } catch (e: any) { - this.log(LogLevel.ERROR, `Error processing discovered device: ${e.message ?? e}`) - } - }) - - // Start scanning with timeout handling - this.noble.startScanningAsync(PRIMARY_SERVICE_UUID_LIST, false) - .then(() => { - this.log(LogLevel.DEBUG, `Started scanning for ${p.duration}ms`) - timer = setTimeout(async () => { - const result = await finishDiscovery() - if (result.length === 0) { - reject(new Error(`No SwitchBot devices found after ${p.duration}ms discovery timeout`)) - } else { - resolve(result) - } - }, p.duration) - }) - .catch((error) => { - this.log(LogLevel.ERROR, `Failed to start scanning: ${error.message ?? error}`) - reject(new Error(`Failed to start BLE scanning: ${error.message ?? error}`)) - }) - }) - } - - /** - * Creates a device object based on the peripheral, id, and model. - * - * @param {NobleTypes['peripheral']} peripheral - The peripheral object. - * @param {string} id - The device id. - * @param {string} model - The device model. - * @returns {Promise} - The device object or null. - */ - private async createDevice(peripheral: NobleTypes['peripheral'], id: ad['id'], model: SwitchBotBLEModel): Promise { - const ad = await Advertising.parse(peripheral, (level: string, message: string) => this.log(level as LogLevel, message)) - if (ad && await this.filterAd(ad, id, model) && this.noble) { - switch (ad.serviceData.model) { - case SwitchBotBLEModel.Bot: return new WoHand(peripheral, this.noble) - case SwitchBotBLEModel.Curtain: - case SwitchBotBLEModel.Curtain3: return new WoCurtain(peripheral, this.noble) - case SwitchBotBLEModel.Humidifier: return new WoHumi(peripheral, this.noble) - case SwitchBotBLEModel.Humidifier2: return new WoHumi2(peripheral, this.noble) - case SwitchBotBLEModel.Meter: return new WoSensorTH(peripheral, this.noble) - case SwitchBotBLEModel.MeterPlus: return new WoSensorTHPlus(peripheral, this.noble) - case SwitchBotBLEModel.MeterPro: return new WoSensorTHPro(peripheral, this.noble) - case SwitchBotBLEModel.MeterProCO2: return new WoSensorTHProCO2(peripheral, this.noble) - case SwitchBotBLEModel.Hub2: return new WoHub2(peripheral, this.noble) - case SwitchBotBLEModel.OutdoorMeter: return new WoIOSensorTH(peripheral, this.noble) - case SwitchBotBLEModel.MotionSensor: return new WoPresence(peripheral, this.noble) - case SwitchBotBLEModel.PresenceSensor: return new WoPresence(peripheral, this.noble) - case SwitchBotBLEModel.ContactSensor: return new WoContact(peripheral, this.noble) - case SwitchBotBLEModel.Remote: return new WoRemote(peripheral, this.noble) - case SwitchBotBLEModel.ColorBulb: return new WoBulb(peripheral, this.noble) - case SwitchBotBLEModel.CeilingLight: - case SwitchBotBLEModel.CeilingLightPro: return new WoCeilingLight(peripheral, this.noble) - case SwitchBotBLEModel.StripLight: return new WoStrip(peripheral, this.noble) - case SwitchBotBLEModel.Leak: return new WoLeak(peripheral, this.noble) - case SwitchBotBLEModel.PlugMiniUS: return new WoPlugMiniUS(peripheral, this.noble) - case SwitchBotBLEModel.PlugMiniJP: return new WoPlugMiniJP(peripheral, this.noble) - case SwitchBotBLEModel.PlugMiniEU: return new WoPlugMiniEU(peripheral, this.noble) - case SwitchBotBLEModel.Lock: return new WoSmartLock(peripheral, this.noble) - case SwitchBotBLEModel.LockPro: return new WoSmartLockPro(peripheral, this.noble) - case (SwitchBotBLEModel.LockUltra as any): return new WoSmartLockUltra(peripheral, this.noble) - case SwitchBotBLEModel.BlindTilt: return new WoBlindTilt(peripheral, this.noble) - case SwitchBotBLEModel.Keypad: return new WoKeypad(peripheral, this.noble) - case SwitchBotBLEModel.RelaySwitch1: return new WoRelaySwitch1(peripheral, this.noble) - case SwitchBotBLEModel.RelaySwitch1PM: return new WoRelaySwitch1PM(peripheral, this.noble) - default: return new SwitchbotDevice(peripheral, this.noble) - } - } - return null - } - - /** - * Filters advertising data based on id and model. - * - * @param {Ad} ad - The advertising data. - * @param {string} id - The device id. - * @param {string} model - The device model. - * @returns {Promise} - True if the advertising data matches the id and model, false otherwise. - */ - private async filterAd(ad: ad, id: string, model: string): Promise { - if (!ad) { - return false - } - if (id && ad.address.toLowerCase().replace(/[^a-z0-9]/g, '') !== id.toLowerCase().replace(/:/g, '')) { - return false - } - if (model && ad.serviceData.model !== model) { - return false - } - return true - } - - /** - * Starts scanning for SwitchBot devices. - * - * @param {Params} [params] - Optional parameters. - * @returns {Promise} - Resolves when scanning starts successfully. - */ - public async startScan(params: Params = {}): Promise { - await this.nobleInitialized - await this.validate(params, { - model: { required: false, type: 'string', enum: Object.values(SwitchBotBLEModel) }, - id: { required: false, type: 'string', min: 12, max: 17 }, - }) - - if (!this.noble) { - throw new Error('noble object failed to initialize') - } - - const p = { model: params.model || '', id: params.id || '' } - - this.noble.removeAllListeners('discover') - - this.noble.on('discover', async (peripheral: NobleTypes['peripheral']) => { - try { - const ad = await Advertising.parse(peripheral, (level: string, message: string) => this.log(level as LogLevel, message)) - this.log(LogLevel.DEBUG, `Advertisement: ${JSON.stringify(ad)}`) - this.log(LogLevel.DEBUG, `Filter ID: ${p.id}`) - this.log(LogLevel.DEBUG, `Filter Model: ${p.model}`) - if (ad && await this.filterAd(ad, p.id, p.model)) { - this.log(LogLevel.DEBUG, `Advertisement passed filter: ${JSON.stringify(ad)}`) - if (this.onadvertisement) { - try { - await this.onadvertisement(ad) - } catch (e: any) { - this.log(LogLevel.ERROR, `Error in onadvertisement callback: ${e.message ?? e}`) - } - } - } - } catch (e: any) { - this.log(LogLevel.ERROR, `Error parsing advertisement: ${e.message ?? e}`) - } - }) - - try { - await this.noble.startScanningAsync(PRIMARY_SERVICE_UUID_LIST, true) - this.log(LogLevel.DEBUG, 'Started Scanning for SwitchBot BLE devices.') - } catch (e: any) { - this.log(LogLevel.ERROR, `startScanningAsync error: ${JSON.stringify(e.message ?? e)}`) - } - } - - /** - * Stops scanning for SwitchBot devices. - * - * @returns {Promise} - Resolves when scanning stops successfully. - */ - public async stopScan(): Promise { - if (!this.noble) { - return - } - - this.noble.removeAllListeners('discover') - try { - await this.noble.stopScanningAsync() - this.log(LogLevel.DEBUG, 'Stopped Scanning for SwitchBot BLE devices.') - } catch (e: any) { - this.log(LogLevel.ERROR, `stopScanningAsync error: ${JSON.stringify(e.message ?? e)}`) - } - } - - /** - * Waits for the specified time. - * - * @param {number} msec - The time to wait in milliseconds. - * @returns {Promise} - Resolves after the specified time. - */ - public async wait(msec: number): Promise { - if (typeof msec !== 'number' || msec < 0) { - throw new Error('Invalid parameter: msec must be a non-negative integer.') - } - - return new Promise(resolve => setTimeout(resolve, msec)) - } -} - -export { LogLevel, SwitchbotDevice } diff --git a/src/switchbot-openapi.test.ts b/src/switchbot-openapi.test.ts deleted file mode 100644 index 1a86775e..00000000 --- a/src/switchbot-openapi.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable import/order */ -/* eslint-disable */ -import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' - -// Mock undici.request in ESM via module mock -vi.mock('undici', async () => { - const actual = await vi.importActual('undici') - return { ...actual, request: vi.fn() } -}) -import * as undici from 'undici' - -// Alias the mocked request function -const requestMock = undici.request as Mock - -import { SwitchBotOpenAPI } from './switchbot-openapi' - -describe('switchBotOpenAPI', () => { - beforeEach(() => { - // Reset module-level undici.request mock - requestMock.mockReset() - }) - - afterEach(() => { - vi.resetAllMocks() - }) - - it('controlDevice should send correct request and parse response', async () => { - const fakeBody = { json: vi.fn().mockResolvedValue({ commandId: 'abc123' }) } - const statusCode = 200 - requestMock.mockResolvedValue({ body: fakeBody, statusCode }) - - const api = new SwitchBotOpenAPI('my-token', 'my-secret') - const result = await api.controlDevice('dev123', 'turnOn', 'default') - - expect(requestMock).toHaveBeenCalledWith( - expect.stringContaining('/dev123/commands'), - expect.objectContaining({ - method: 'POST', - headers: expect.any(Object), - body: JSON.stringify({ command: 'turnOn', parameter: 'default', commandType: 'command' }), - }), - ) - expect(result.response).toEqual({ commandId: 'abc123' }) - expect(result.statusCode).toBe(statusCode) - }) -}) diff --git a/src/switchbot-openapi.ts b/src/switchbot-openapi.ts deleted file mode 100644 index aa1f5757..00000000 --- a/src/switchbot-openapi.ts +++ /dev/null @@ -1,393 +0,0 @@ -/* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. - * - * switchbot-openapi.ts: Switchbot BLE API registration. - */ -import type { IncomingMessage, Server, ServerResponse } from 'node:http' - -import type { commandType, deleteWebhookResponse, devices, deviceStatus, deviceStatusRequest, pushRequest, pushResponseBody, queryWebhookResponse, setupWebhookResponse, updateWebhookResponse } from './types/openapi.js' - -import crypto, { randomUUID } from 'node:crypto' -import { EventEmitter } from 'node:events' -import { createServer } from 'node:http' - -import { request } from 'undici' - -import { updateBaseURL, urls } from './settings.js' - -/** - * Custom error class for API errors. - */ -class APIError extends Error { - constructor(message: string, public statusCode?: number) { - super(message) - this.name = 'APIError' - } -} - -/** - * The `SwitchBotOpenAPI` class provides methods to interact with the SwitchBot OpenAPI. - * It allows you to retrieve device information, control devices, and manage webhooks. - * - * @extends EventEmitter - * - * @example - * ```typescript - * const switchBotAPI = new SwitchBotOpenAPI('your-token', 'your-secret'); - * - * // Get devices - * switchBotAPI.getDevices().then(response => { - * console.log(response); - * }).catch(error => { - * console.error(error); - * }); - * - * // Control a device - * switchBotAPI.controlDevice('device-id', 'turnOn', 'default').then(response => { - * console.log(response); - * }).catch(error => { - * console.error(error); - * }); - * - * // Setup webhook - * switchBotAPI.setupWebhook('http://your-webhook-url').then(() => { - * console.log('Webhook setup successfully'); - * }).catch(error => { - * console.error(error); - * }); - * ``` - * - * @param {string} token - The API token used for authentication. - * @param {string} secret - The secret key used for signing requests. - */ -export class SwitchBotOpenAPI extends EventEmitter { - private token: string - private secret: string - - webhookEventListener?: Server | null = null - - /** - * Creates an instance of the SwitchBot OpenAPI client. - * - * @param token - The API token used for authentication. - * @param secret - The secret key used for signing requests. - */ - constructor(token: string, secret: string, hostname?: string) { - super() - this.token = token - this.secret = secret - // Log instance creation and token (secret is hidden) - this.emitLog('info', 'SwitchBotOpenAPI instance created') - this.emitLog('debug', `Token: ${token}`) - // Update baseURL if custom hostname provided - if (hostname) { - updateBaseURL(hostname) - } - } - - /** - * Emits a log event with the specified log level and message. - * - * @param level - The severity level of the log (e.g., 'info', 'warn', 'error'). - * @param message - The log message to be emitted. - */ - private async emitLog(level: string, message: string): Promise { - this.emit('log', { level, message }) - } - - /** - * Generates the headers required for authentication with the SwitchBot OpenAPI. - * - * @param configToken - The token used for authorization. - * @param configSecret - The secret key used to sign the request. - * @returns An object containing the necessary headers: - * - `Authorization`: The authorization token. - * - `sign`: The HMAC-SHA256 signature of the token, timestamp, and nonce. - * - `nonce`: A unique identifier for the request. - * - `t`: The current timestamp in milliseconds. - * - `Content-Type`: The content type of the request, set to 'application/json'. - */ - private generateHeaders = (configToken: string, configSecret: string): { 'Authorization': string, 'sign': string, 'nonce': string, 't': string, 'Content-Type': string } => { - const t = Date.now().toString() - const nonce = randomUUID() - const data = configToken + t + nonce - const sign = crypto - .createHmac('sha256', configSecret) - .update(data) - .digest('base64') - - return { - 'Authorization': configToken, - 'sign': sign, - 'nonce': nonce, - 't': t, - 'Content-Type': 'application/json', - } - } - - /** - * Retrieves the list of devices from the SwitchBot OpenAPI. - * @param token - (Optional) The token used for authentication. If not provided, the instance token will be used. - * @param secret - (Optional) The secret used for authentication. If not provided, the instance secret will be used. - * @returns {Promise<{ response: body, statusCode: number }>} A promise that resolves to an object containing the API response. - * @throws {Error} Throws an error if the request to get devices fails. - */ - async getDevices(token?: string, secret?: string): Promise<{ response: devices, statusCode: number }> { - const url = urls.devicesURL - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const { body, statusCode } = await request(url, { headers: this.generateHeaders(configToken, configSecret) }) - const response = await body.json() as devices - this.emitLog('debug', `Got devices: ${JSON.stringify(response)}`) - this.emitLog('debug', `statusCode: ${statusCode}`) - return { response, statusCode } - } catch (e: any) { - this.emitLog('error', `Failed to get devices: ${e.message ?? e}`) - throw new APIError(`Failed to get devices: ${e.message ?? e}`, e.statusCode) - } - } - - /** - * Controls a device by sending a command to the SwitchBot API. - * - * @param deviceId - The ID of the device to control. - * @param command - The command to send to the device. - * @param parameter - The parameter for the command. - * @param commandType - The type of the command (default is 'command'). - * @param token - (Optional) The token used for authentication. If not provided, the instance token will be used. - * @param secret - (Optional) The secret used for authentication. If not provided, the instance secret will be used. - * @returns A promise that resolves to an object containing the response body and status code. - * @throws An error if the device control fails. - */ - async controlDevice( - deviceId: string, - command: string, - parameter: string, - commandType: commandType = 'command', - token?: string, - secret?: string, - ): Promise<{ response: pushResponseBody, statusCode: number }> { - try { - const configToken = token || this.token - const configSecret = secret || this.secret - // Build request payload - const payload: pushRequest = { command, parameter, commandType } - const { body, statusCode } = await request( - `${urls.devicesURL}/${deviceId}/commands`, - { - method: 'POST', - headers: this.generateHeaders(configToken, configSecret), - body: JSON.stringify(payload), - }, - ) - const response = (await body.json()) as pushResponseBody - this.emitLog('debug', `Controlled device: ${deviceId} with command: ${command} and parameter: ${parameter}`) - this.emitLog('debug', `statusCode: ${statusCode}`) - return { response, statusCode } - } catch (e: any) { - this.emitLog('error', `Failed to control device: ${e.message ?? e}`) - throw new APIError(`Failed to control device: ${e.message ?? e}`, e.statusCode) - } - } - - /** - * Retrieves the status of a specific device. - * - * @param deviceId - The unique identifier of the device. - * @param token - (Optional) The token used for authentication. If not provided, the instance token will be used. - * @param secret - (Optional) The secret used for authentication. If not provided, the instance secret will be used. - * @returns A promise that resolves to an object containing the device status and the status code of the request. - * @throws An error if the request fails. - */ - async getDeviceStatus(deviceId: string, token?: string, secret?: string): Promise<{ response: deviceStatus, statusCode: deviceStatusRequest['statusCode'] }> { - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const { body, statusCode } = await request(`${urls.devicesURL}/${deviceId}/status`, { headers: this.generateHeaders(configToken, configSecret) }) - const { body: response } = await body.json() as deviceStatusRequest - this.emitLog('debug', `Got device status: ${deviceId}`) - this.emitLog('debug', `statusCode: ${statusCode}`) - return { response, statusCode } - } catch (error: any) { - this.emitLog('error', `Failed to get device status: ${error.message}`) - throw new APIError(`Failed to get device status: ${error.message}`, error.statusCode) - } - } - - /** - * Sets up a webhook listener and configures the webhook on the server. - * - * This method performs the following steps: - * 1. Creates a local server to listen for incoming webhook events. - * 2. Sends a request to set up the webhook with the provided URL. - * 3. Sends a request to update the webhook configuration. - * 4. Sends a request to query the current webhook URL. - * - * @param url - The URL to which the webhook events will be sent. - * @param token - (Optional) The token used for authentication. If not provided, the instance token will be used. - * @param secret - (Optional) The secret used for authentication. If not provided, the instance secret will be used. - * @returns A promise that resolves when the webhook setup is complete. - * - * @throws Will log an error if any step in the webhook setup process fails. - */ - async setupWebhook(url: string, token?: string, secret?: string): Promise { - try { - // Close existing listener if any to avoid port conflicts - if (this.webhookEventListener) { - this.webhookEventListener.close() - this.webhookEventListener = null - } - const xurl = new URL(url) - const port = Number(xurl.port) - const path = xurl.pathname - this.webhookEventListener = createServer(async (request: IncomingMessage, response: ServerResponse) => { - try { - if (request.url === path && request.method === 'POST') { - request.on('data', async (data) => { - try { - const body = JSON.parse(data) - await this.emitLog('debug', `Received Webhook: ${JSON.stringify(body)}`) - this.emit('webhookEvent', body) - } catch (e: any) { - await this.emitLog('error', `Failed to handle webhook event data, Error: ${e.message ?? e}`) - } - }) - response.writeHead(200, { 'Content-Type': 'text/plain' }) - response.end('OK') - } else { - await this.emitLog('error', `Invalid request received. URL:${request.url}, Method:${request.method}`) - response.writeHead(403, { 'Content-Type': 'text/plain' }) - response.end(`NG`) - } - } catch (e: any) { - await this.emitLog('error', `Failed to handle webhook event, Error: ${e.message ?? e}`) - } - }).listen(port || 80) - } catch (e: any) { - await this.emitLog('error', `Failed to create webhook listener, Error: ${e.message ?? e}`) - throw new APIError(`Failed to create webhook listener: ${e.message ?? e}`, e.statusCode) - } - - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const requestOptions = { - method: 'POST', - headers: this.generateHeaders(configToken, configSecret), - body: JSON.stringify({ - action: 'setupWebhook', - url, - deviceList: 'ALL', - }), - timeout: 20000, // Increase timeout to 20 seconds - } - const { body, statusCode } = await requestWithRetry(urls.setupWebhook, requestOptions) - const response: any = await body.json() as setupWebhookResponse['body'] - await this.emitLog('debug', `setupWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`) - if (statusCode !== 200 || response?.statusCode !== 100) { - await this.emitLog('error', `Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`) - } - } catch (e: any) { - await this.emitLog('error', `Failed to configure webhook, Error: ${e.message ?? e}`) - throw new APIError(`Failed to configure webhook: ${e.message ?? e}`, e.statusCode) - } - - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const { body, statusCode } = await request(urls.updateWebhook, { - method: 'POST', - headers: this.generateHeaders(configToken, configSecret), - body: JSON.stringify({ - action: 'updateWebhook', - config: { - url, - enable: true, - }, - }), - }) - const response: any = await body.json() as updateWebhookResponse['body'] - await this.emitLog('debug', `updateWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`) - if (statusCode !== 200 || response?.statusCode !== 100) { - await this.emitLog('error', `Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`) - } - } catch (e: any) { - await this.emitLog('error', `Failed to update webhook, Error: ${e.message ?? e}`) - throw new APIError(`Failed to update webhook: ${e.message ?? e}`, e.statusCode) - } - - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const { body, statusCode } = await request(urls.queryWebhook, { - method: 'POST', - headers: this.generateHeaders(configToken, configSecret), - body: JSON.stringify({ - action: 'queryUrl', - }), - }) - const response: any = await body.json() as queryWebhookResponse['body'] - await this.emitLog('debug', `queryWebhook: body:${JSON.stringify(response)}, statusCode:${statusCode}`) - if (statusCode !== 200 || response?.statusCode !== 100) { - await this.emitLog('error', `Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`) - } else { - await this.emitLog('info', `Listening webhook on ${response?.body?.urls[0]}`) - } - } catch (e: any) { - await this.emitLog('error', `Failed to query webhook, Error: ${e.message ?? e}`) - throw new APIError(`Failed to query webhook: ${e.message ?? e}`, e.statusCode) - } - } - - /** - * Deletes a webhook by sending a request to the specified URL. - * - * @param url - The URL of the webhook to be deleted. - * @param token - (Optional) The token used for authentication. If not provided, the instance token will be used. - * @param secret - (Optional) The secret used for authentication. If not provided, the instance secret will be used. - * @returns A promise that resolves when the webhook is successfully deleted. - * - * @throws Will log an error if the deletion fails. - */ - async deleteWebhook(url: string, token?: string, secret?: string): Promise { - try { - const configToken = token || this.token - const configSecret = secret || this.secret - const { body, statusCode } = await request(urls.deleteWebhook, { - method: 'POST', - headers: this.generateHeaders(configToken, configSecret), - body: JSON.stringify({ - action: 'deleteWebhook', - url, - }), - }) - const response: any = await body.json() as deleteWebhookResponse['body'] - await this.emitLog('debug', `deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`) - if (statusCode !== 200 || response?.statusCode !== 100) { - await this.emitLog('error', `Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`) - } else { - await this.emitLog('info', 'Unregistered webhook to close listening.') - // Close listener server - if (this.webhookEventListener) { - this.webhookEventListener.close() - this.webhookEventListener = null - } - } - } catch (e: any) { - await this.emitLog('error', `Failed to delete webhook, Error: ${e.message ?? e}`) - throw new APIError(`Failed to delete webhook: ${e.message ?? e}`, e.statusCode) - } - } -} -async function requestWithRetry(url: string, options: any, retries: number = 3): Promise { - for (let attempt = 1; attempt <= retries; attempt++) { - try { - return await request(url, options) - } catch (error: any) { - if (attempt === retries) { - throw error - } - await new Promise(resolve => setTimeout(resolve, 1000 * attempt)) // Exponential backoff - } - } -} diff --git a/src/switchbot.ts b/src/switchbot.ts new file mode 100644 index 00000000..0fa6732a --- /dev/null +++ b/src/switchbot.ts @@ -0,0 +1,631 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * switchbot.ts: SwitchBot v4.0.0 - Main Hybrid BLE/API Class + */ + +import type { SwitchBotDevice } from './devices/base.js' +import type { ConnectionType, DiscoveryOptions, LogLevel, SwitchBotConfig } from './types/index.js' + +import { EventEmitter } from 'node:events' + +import { OpenAPIClient } from './api.js' +import { BLEConnection, BLEScanner } from './ble.js' +import { DeviceManager } from './devices/base.js' +import { WoAIHub } from './devices/wo-ai-hub.js' +import { WoAirPurifierPM25 } from './devices/wo-air-purifier-pm25.js' +import { WoAirPurifierTable } from './devices/wo-air-purifier-table.js' +import { WoAirPurifier } from './devices/wo-air-purifier.js' +import { WoArtFrame } from './devices/wo-art-frame.js' +import { WoBlindTilt } from './devices/wo-blind-tilt.js' +import { WoBulb } from './devices/wo-bulb.js' +import { WoCandleWarmerLamp } from './devices/wo-candle-warmer-lamp.js' +import { WoCeilingLight } from './devices/wo-ceiling-light.js' +import { WoCirculatorFan } from './devices/wo-circulator-fan.js' +import { WoClimatePanel } from './devices/wo-climate-panel.js' +import { WoContact } from './devices/wo-contact.js' +import { WoCurtain } from './devices/wo-curtain.js' +import { WoFloorLamp } from './devices/wo-floor-lamp.js' +import { WoGarageDoorOpener } from './devices/wo-garage-door-opener.js' +import { WoHand } from './devices/wo-hand.js' +import { WoHub2 } from './devices/wo-hub2.js' +import { WoHub3 } from './devices/wo-hub3.js' +import { WoHubMiniMatter } from './devices/wo-hubmini-matter.js' +import { WoHumi2 } from './devices/wo-humi2.js' +import { WoHumi } from './devices/wo-humi.js' +import { WoIOSensorTH } from './devices/wo-io-sensor-th.js' +import { WoKeypadVisionPro } from './devices/wo-keypad-vision-pro.js' +import { WoKeypadVision } from './devices/wo-keypad-vision.js' +import { WoKeypad } from './devices/wo-keypad.js' +import { WoLeak } from './devices/wo-leak.js' +import { WoSmartLockLite } from './devices/wo-lock-lite.js' +import { WoSmartLockProWiFi } from './devices/wo-lock-pro-wifi.js' +import { WoSmartLockPro } from './devices/wo-lock-pro.js' +import { WoSmartLockVisionPro } from './devices/wo-lock-vision-pro.js' +import { WoSmartLockVision } from './devices/wo-lock-vision.js' +import { WoSmartLock } from './devices/wo-lock.js' +import { WoPanTiltCamPlus3K } from './devices/wo-pan-tilt-cam-plus-3k.js' +import { WoPlugMiniJP } from './devices/wo-plug-mini-jp.js' +import { WoPlugMiniUS } from './devices/wo-plug-mini-us.js' +import { WoPresence } from './devices/wo-presence.js' +import { WoRelaySwitch1 } from './devices/wo-relay-switch-1.js' +import { WoRelaySwitch1PM } from './devices/wo-relay-switch-1pm.js' +import { WoRelaySwitch2PM } from './devices/wo-relay-switch-2pm.js' +import { WoRemoteWithScreen } from './devices/wo-remote-with-screen.js' +import { WoRemote } from './devices/wo-remote.js' +import { WoRGBICBulb } from './devices/wo-rgbic-bulb.js' +import { WoRGBICNeonWireRopeLight } from './devices/wo-rgbic-neon-wire-rope-light.js' +import { WoRGBICWWFloorLamp } from './devices/wo-rgbicww-floor-lamp.js' +import { WoRGBICWWStripLight } from './devices/wo-rgbicww-strip-light.js' +import { WoRollerShade } from './devices/wo-roller-shade.js' +import { WoSensorTHPlus } from './devices/wo-sensor-th-plus.js' +import { WoSensorTHProCO2 } from './devices/wo-sensor-th-pro-co2.js' +import { WoSensorTHPro } from './devices/wo-sensor-th-pro.js' +import { WoSensorTH } from './devices/wo-sensor-th.js' +import { WoSmartThermostatRadiator } from './devices/wo-smart-thermostat-radiator.js' +import { WoStripLight3 } from './devices/wo-strip-light-3.js' +import { WoStrip } from './devices/wo-strip.js' +import { WoVacuumK10Plus } from './devices/wo-vacuum-k10-plus.js' +import { WoVacuumK10ProCombo } from './devices/wo-vacuum-k10-pro-combo.js' +import { WoVacuumK10Pro } from './devices/wo-vacuum-k10-pro.js' +import { WoVacuumK11Plus } from './devices/wo-vacuum-k11-plus.js' +import { WoVacuumK20 } from './devices/wo-vacuum-k20.js' +import { WoVacuumS10 } from './devices/wo-vacuum-s10.js' +import { WoVacuumS20 } from './devices/wo-vacuum-s20.js' +import { WoVacuum } from './devices/wo-vacuum.js' +import { WoWaterDetector } from './devices/wo-water-detector.js' +import { BLE_SUPPORTED, DEFAULTS, DEVICE_CLASS_MAP } from './settings.js' +import { Logger, macToDeviceId } from './utils/index.js' + +/** + * Device class constructor type + */ +type DeviceConstructor = new (info: any, options: any) => SwitchBotDevice + +/** + * Device class registry + */ +const DEVICE_CLASSES: Record = { + WoHand, + WoCurtain, + WoRollerShade, + WoSmartLock, + WoSmartLockLite, + WoSmartLockPro, + WoSmartLockProWiFi, + WoSmartThermostatRadiator, + WoSmartLockVision, + WoSmartLockVisionPro, + WoSensorTH, + WoSensorTHPlus, + WoSensorTHPro, + WoSensorTHProCO2, + WoIOSensorTH, + WoContact, + WoPresence, + WoPlugMiniUS, + WoPlugMiniJP, + WoPlugMiniEU: WoPlugMiniUS, // Use same class + WoBulb, + WoStrip, + WoStripLight3, + WoRGBICWWStripLight, + WoArtFrame, + WoCeilingLight, + WoCirculatorFan, + WoClimatePanel, + WoFloorLamp, + WoBlindTilt, + WoHumi, + WoHumi2, + WoAirPurifier, + WoAirPurifierTable, + WoHub2, + WoHub3, + WoHubMiniMatter, + WoLeak, + WoGarageDoorOpener, + WoRelaySwitch1, + WoRelaySwitch1PM, + WoRelaySwitch2PM, + WoRemote, + WoRGBICBulb, + WoRGBICWWFloorLamp, + WoKeypad, + WoKeypadVision, + WoKeypadVisionPro, + WoVacuumK10Plus, + WoVacuumK10ProCombo, + WoVacuumK10Pro, + WoVacuumK11Plus, + WoVacuumK20, + WoVacuumS10, + WoVacuumS20, + WoVacuum, + WoAirPurifierPM25, + WoRGBICNeonWireRopeLight, + WoCandleWarmerLamp, + WoPanTiltCamPlus3K, + WoRemoteWithScreen, + WoAIHub, + WoWaterDetector, +} + +/** + * Main SwitchBot class - Hybrid BLE/API with automatic fallback + */ +export class SwitchBot extends EventEmitter { + private config: Required + private logger: Logger + private bleScanner?: BLEScanner + private bleConnection?: BLEConnection + private apiClient?: OpenAPIClient + private deviceManager: DeviceManager + private initialized = false + // Track pending device creations for async API discovery + private _pendingDeviceCreations: Promise[] = [] + + constructor(config: SwitchBotConfig = {}) { + super() + + // Set defaults + this.config = { + token: config.token || '', + secret: config.secret || '', + baseURL: config.baseURL || DEFAULTS.baseURL, + enableBLE: config.enableBLE ?? (BLE_SUPPORTED && DEFAULTS.enableBLE), + scanTimeout: config.scanTimeout || DEFAULTS.scanTimeout, + enableFallback: config.enableFallback ?? DEFAULTS.enableFallback, + logLevel: config.logLevel ?? DEFAULTS.logLevel, + noble: config.noble, + enableConnectionIntelligence: config.enableConnectionIntelligence ?? true, + enableCircuitBreaker: config.enableCircuitBreaker ?? true, + enableRetry: config.enableRetry ?? true, + maxRetryAttempts: config.maxRetryAttempts ?? 3, + retryInitialDelayMs: config.retryInitialDelayMs ?? 100, + retryMaxDelayMs: config.retryMaxDelayMs ?? 5000, + detailedErrors: config.detailedErrors ?? false, + logger: config.logger ?? { + error: () => {}, + warn: () => {}, + info: () => {}, + debug: () => {}, + }, + _internal: config._internal ?? {}, + } + + this.logger = new Logger('SwitchBot', this.config.logLevel) + this.deviceManager = new DeviceManager(this.config.logLevel) + + // Initialize based on configuration + this.initialize() + } + + /** + * Initialize BLE and API clients + */ + private initialize(): void { + // Initialize BLE if enabled and supported + if (this.config.enableBLE) { + if (!BLE_SUPPORTED) { + this.logger.warn('BLE not supported on this platform (Linux/macOS only)') + } else { + try { + this.bleScanner = new BLEScanner({ + noble: this.config.noble, + logLevel: this.config.logLevel, + }) + + this.bleConnection = new BLEConnection({ + noble: this.config.noble, + logLevel: this.config.logLevel, + }) + + this.logger.info('BLE initialized') + } catch (error) { + this.logger.error('Failed to initialize BLE', error) + } + } + } + + // Initialize OpenAPI if credentials provided + if (this.config.token && this.config.secret) { + try { + this.apiClient = new OpenAPIClient( + this.config.token, + this.config.secret, + this.config.baseURL, + this.config.logLevel, + ) + + this.logger.info('OpenAPI client initialized') + } catch (error) { + this.logger.error('Failed to initialize OpenAPI client', error) + } + } + + // Check if at least one method is available + if (!this.bleScanner && !this.apiClient) { + this.logger.warn('No discovery methods available - provide OpenAPI credentials or enable BLE') + } + + this.initialized = true + } + + /** + * Discover devices (BLE + OpenAPI) + * BLE discovery runs first, then API discovery to enable proper device matching + */ + async discover(options: DiscoveryOptions = {}): Promise { + if (!this.initialized) { + throw new Error('SwitchBot not initialized') + } + + const { + scanBLE = !!this.bleScanner, + fetchAPI = !!this.apiClient, + timeout = this.config.scanTimeout, + } = options + + this.logger.info('Starting device discovery', { scanBLE, fetchAPI }) + + // BLE discovery first (sequential) + if (scanBLE && this.bleScanner) { + this.logger.info('Step 1: Starting BLE discovery...') + try { + await this.discoverBLE(timeout) + this.logger.info('Step 1: BLE discovery complete') + } catch (err) { + this.logger.error('BLE discovery failed', { + error: err, + message: (err as any)?.message, + stack: (err as any)?.stack, + }) + } + } + + // API discovery second (sequential) + if (fetchAPI && this.apiClient) { + this.logger.info('Step 2: Starting API discovery...') + try { + await this.discoverAPI() + this.logger.info('Step 2: API discovery complete') + } catch (err) { + this.logger.error('API discovery failed (outer)', { + error: err, + message: (err as any)?.message, + stack: (err as any)?.stack, + }) + } + } + + // Wait for all pending device creations to finish (API discovery is async) + if (this._pendingDeviceCreations && this._pendingDeviceCreations.length > 0) { + await Promise.all(this._pendingDeviceCreations) + this._pendingDeviceCreations = [] + } + + const devices = this.deviceManager.list() + this.logger.info(`Discovery complete: ${devices.length} unique devices found`) + this.emit('discovery-complete', devices) + + return devices + } + + /** + * Discover devices via BLE + */ + private async discoverBLE(timeout: number): Promise { + if (!this.bleScanner || !this.bleConnection) { + return + } + + this.logger.info('Starting BLE discovery') + // Listen for discoveries + const handler = (advertisement: any) => { + this.handleBLEDiscovery(advertisement) + } + + this.bleScanner.on('discover', handler) + + try { + await this.bleScanner.startScan({ duration: timeout }) + + // Wait for scan to complete + await new Promise(resolve => setTimeout(resolve, timeout)) + } catch (err) { + this.logger.error('BLE scan error', { + error: err, + message: (err as any)?.message, + stack: (err as any)?.stack, + }) + throw err + } finally { + this.bleScanner.off('discover', handler) + } + } + + /** + * Handle BLE device discovery + */ + private async handleBLEDiscovery(advertisement: any): Promise { + const { id: advertisementId, address, serviceData, rssi } = advertisement + const deviceType = serviceData.modelName + const mac = typeof address === 'string' && address.length > 0 ? address : undefined + const deviceId = mac ? macToDeviceId(mac) : advertisementId + + if (!deviceId) { + this.logger.warn(`Skipping ${deviceType} BLE discovery: no address or advertisement id`) + return + } + + // Create device info + const info = { + id: deviceId, + name: deviceType, + deviceType, + mac, + bleId: advertisementId, + connectionTypes: ['ble'] as any, + activeConnection: undefined, + battery: serviceData.battery, + bleServiceData: serviceData, + rssi, + } + + // Check if device already exists (may have been discovered via API) + const device = this.deviceManager.get(info.id) + + if (device) { + // Update existing device info + device.updateInfo({ + mac: mac ?? device.getInfo().mac, + connectionTypes: [...new Set([...device.getInfo().connectionTypes, 'ble' as ConnectionType])], + battery: serviceData.battery, + bleServiceData: serviceData, + rssi, + }) + this.logger.debug(`Updated device: ${info.name} (${info.id})`) + } else { + // Create new device + const newDevice = await this.createDevice(info) + if (newDevice) { + this.deviceManager.add(newDevice) + this.emit('device-discovered', newDevice) + this.logger.info(`Discovered ${info.name} via BLE (${info.id})`) + } + } + } + + /** + * Discover devices via OpenAPI + */ + private async discoverAPI(): Promise { + if (!this.apiClient) { + return + } + + this.logger.info('Starting API discovery') + + try { + const response = await this.apiClient.getDevices() + this.logger.debug('API getDevices() raw response', { + statusCode: (response as any)?.statusCode, + response, + }) + + // Track all pending device creations + if (!this._pendingDeviceCreations) { + this._pendingDeviceCreations = [] + } + for (const apiDevice of response.deviceList) { + this._pendingDeviceCreations.push(this.handleAPIDiscovery(apiDevice)) + } + } catch (error) { + this.logger.error('API discovery failed', { + error, + message: (error as any)?.message, + stack: (error as any)?.stack, + statusCode: (error as any)?.statusCode, + response: (error as any)?.response, + }) + throw error + } + } + + /** + * Handle API device discovery + * Tries to match with existing BLE devices and combines them into one entry + */ + private async handleAPIDiscovery(apiDevice: any): Promise { + const { deviceId, deviceName, deviceType, enableCloudService, hubDeviceId, version } = apiDevice + + this.logger.debug(`Processing API device: ${deviceName} (${deviceId}, type: ${deviceType})`) + + // Try to find matching BLE device + // Strategy: look for BLE devices of the same type that haven't been fully populated yet + const matchedBLEDevice = this.findMatchingBLEDevice(deviceType, deviceName) + + if (matchedBLEDevice) { + // Update existing BLE device with API information + const deviceId_internal = matchedBLEDevice.getId() + matchedBLEDevice.updateInfo({ + name: deviceName, + connectionTypes: [...new Set([...matchedBLEDevice.getInfo().connectionTypes, 'api' as ConnectionType])], + hubDeviceId, + version, + cloudServiceEnabled: enableCloudService, + }) + this.logger.info(`Matched API device to existing BLE device: ${deviceName} (${deviceId_internal})`) + this.emit('device-updated', matchedBLEDevice) + } else { + // No matching BLE device found, create new API-only device + const info = { + id: deviceId, + name: deviceName, + deviceType, + connectionTypes: ['api'] as any, + activeConnection: undefined, + hubDeviceId, + version, + cloudServiceEnabled: enableCloudService, + } + + // Check if device already exists (shouldn't happen but safety check) + const device = this.deviceManager.get(info.id) + + if (!device) { + // Await device creation and addition + const newDevice = await this.createDevice(info) + if (newDevice) { + this.deviceManager.add(newDevice) + this.emit('device-discovered', newDevice) + this.logger.info(`Discovered ${deviceName} via API only (${deviceId})`) + } + } + } + } + + /** + * Find matching BLE device for an API device + * Returns a BLE device if a good match is found + */ + private findMatchingBLEDevice(apiDeviceType: string, apiDeviceName: string): SwitchBotDevice | undefined { + // Get all BLE devices + const bleDevices = this.deviceManager.list().filter((device) => { + const info = device.getInfo() + return info.connectionTypes.includes('ble') && !info.connectionTypes.includes('api') + }) + + // Try exact device type match first + const typeMatches = bleDevices.filter(device => device.getDeviceType() === apiDeviceType) + + if (typeMatches.length === 1) { + // If only one device of this type, it's likely a match + this.logger.debug(`Found exact type match for ${apiDeviceType}`) + return typeMatches[0] + } + + if (typeMatches.length > 1) { + // If multiple devices of same type, try to match by name similarity + const nameMatch = typeMatches.find((device) => { + const devName = device.getName() + // Simple name comparison (could be enhanced) + return devName === apiDeviceName || devName.includes(apiDeviceName) || apiDeviceName.includes(devName) + }) + + if (nameMatch) { + this.logger.debug(`Found name match for ${apiDeviceName}`) + return nameMatch + } + + // No good name match, return the first one as fallback for single device + // (better to merge than to duplicate) + if (typeMatches.length === 1) { + return typeMatches[0] + } + } + + return undefined + } + + /** + * Create device instance + */ + private async createDevice(info: any): Promise { + const className = DEVICE_CLASS_MAP[info.deviceType] + this.logger.debug(`createDevice: deviceType='${info.deviceType}', resolved className='${className}', info=`, info) + if (!className) { + this.logger.warn(`createDevice: Unknown device type: ${info.deviceType}`) + return undefined + } + const DeviceClass = DEVICE_CLASSES[className] + this.logger.debug(`createDevice: DeviceClass for '${className}' is ${DeviceClass ? 'found' : 'undefined'}`) + if (!DeviceClass) { + this.logger.warn(`createDevice: Device class not implemented: ${className}`) + return undefined + } + try { + // Use utility to extract all device-relevant options from config + const { extractDeviceOptionsFromConfig } = await import('./utils/index.js') + return new DeviceClass(info, { + ...extractDeviceOptionsFromConfig(this.config), + }) + } catch (error) { + this.logger.error(`createDevice: Failed to create device ${className}`, error) + return undefined + } + } + + /** + * Get device manager (for accessing devices) + */ + get devices(): DeviceManager { + return this.deviceManager + } + + /** + * Get BLE scanner (if available) + */ + getBLEScanner(): BLEScanner | undefined { + return this.bleScanner + } + + /** + * Get API client (if available) + */ + getAPIClient(): OpenAPIClient | undefined { + return this.apiClient + } + + /** + * Get configuration + */ + getConfig(): Required { + return { ...this.config } + } + + /** + * Set log level + */ + setLogLevel(level: LogLevel): void { + this.config.logLevel = level + this.logger.setLevel(level) + + // Update all device log levels + for (const device of this.deviceManager.list()) { + (device as any).logger?.setLevel(level) + } + } + + /** + * Check if BLE is available + */ + isBLEAvailable(): boolean { + return !!this.bleScanner && !!this.bleConnection + } + + /** + * Check if API is available + */ + isAPIAvailable(): boolean { + return !!this.apiClient + } + + /** + * Cleanup and disconnect + */ + async cleanup(): Promise { + this.logger.info('Cleaning up') + + if (this.bleScanner) { + this.bleScanner.destroy() + } + + if (this.bleConnection) { + await this.bleConnection.disconnectAll() + } + + this.deviceManager.clear() + this.emit('cleanup') + } +} diff --git a/src/types/api.ts b/src/types/api.ts new file mode 100644 index 00000000..d212c685 --- /dev/null +++ b/src/types/api.ts @@ -0,0 +1,271 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * types/api.ts: SwitchBot v4.0.0 - OpenAPI Type Definitions + */ + +/** + * OpenAPI Response base + */ +export interface APIResponse { + statusCode: number + message: string + body: T +} + +/** + * Device list response from OpenAPI + */ +export interface DeviceListResponse { + deviceList: APIDevice[] + infraredRemoteList?: APIInfraredRemote[] +} + +/** + * Device information from OpenAPI + */ +export interface APIDevice { + deviceId: string + deviceName: string + deviceType: string + enableCloudService: boolean + hubDeviceId: string + curtainDevicesIds?: string[] + calibrate?: boolean + openDirection?: 'left' | 'right' + master?: boolean + group?: boolean + moving?: boolean + slidePosition?: number + version?: string + lockType?: 'unlatch' | 'latch' + groupName?: string + keyList?: Array<{ + id: number + name: string + type: string + keyId: string + status: 'enabled' | 'disabled' + createTime: number + }> +} + +/** + * Infrared remote device from OpenAPI + */ +export interface APIInfraredRemote { + deviceId: string + deviceName: string + remoteType: string + hubDeviceId: string +} + +/** + * Device status from OpenAPI + */ +export interface APIDeviceStatus { + deviceId: string + deviceType: string + hubDeviceId: string + power?: 'on' | 'off' + version?: string + battery?: number + // Curtain + calibrate?: boolean + group?: boolean + moving?: boolean + slidePosition?: number + // Lock + lockState?: 'locked' | 'unlocked' | 'jammed' + doorState?: 'opened' | 'closed' | 'unknown' + // Meter + temperature?: number + humidity?: number + // Contact + openState?: 'open' | 'closed' | 'timeout' + moveDetected?: boolean + lightLevel?: number | 'bright' | 'dim' | 'dark' + // Motion + // Plug + voltage?: number + weight?: number + electricityOfDay?: number + electricCurrent?: number + // Bulb/Strip/Ceiling + brightnessLevel?: number + color?: string + colorTemperature?: number + // Bot mode + botMode?: 'press' | 'switch' | 'customize' + // Humidifier + nebulizationEfficiency?: number + auto?: boolean + childLock?: boolean + sound?: boolean + lackWater?: boolean + // Air Purifier + fanSpeed?: number + airMode?: 'auto' | 'manual' | 'sleep' + pm25?: number + // Leak + waterLeakDetected?: boolean +} + +/** + * Command request to OpenAPI + */ +export interface APICommandRequest { + command: string + parameter?: string | number | any + commandType?: string +} + +/** + * Command response from OpenAPI + */ +export interface APICommandResponse { + statusCode: number + message: string + body: any +} + +/** + * Scene list response + */ +export interface SceneListResponse { + sceneList: APIScene[] +} + +/** + * Scene from OpenAPI + */ +export interface APIScene { + sceneId: string + sceneName: string +} + +/** + * Webhook configuration + */ +export interface WebhookConfig { + url: string + deviceList?: 'ALL' | string +} + +/** + * Webhook setup response + */ +export interface WebhookSetupResponse { + statusCode: number + message: string + body: any +} + +/** + * Webhook query response + */ +export interface WebhookQueryResponse { + statusCode: number + message: string + body: { + urls: Array<{ + url: string + createTime: number + lastUpdateTime: number + deviceList: string + }> + } +} + +/** + * Webhook details + */ +export interface WebhookDetails { + url: string + createTime: number + lastUpdateTime: number + deviceList: string + enable: boolean +} + +/** + * OpenAPI error response + */ +export interface APIErrorResponse { + statusCode: number + message: string + body?: any +} + +/** + * OpenAPI request headers + */ +export interface APIHeaders { + 'Authorization': string + 'Content-Type': string + 't': string + 'sign': string + 'nonce': string +} + +/** + * Physical device types supported by OpenAPI + */ +export type PhysicalDeviceType + = | 'Bot' + | 'Curtain' + | 'Curtain3' + | 'Plug' + | 'Plug Mini (US)' + | 'Plug Mini (JP)' + | 'Meter' + | 'Meter Plus' + | 'Meter Pro' + | 'Meter Pro (CO2)' + | 'Outdoor Meter' + | 'Lock' + | 'Lock Pro' + | 'Keypad' + | 'Keypad Touch' + | 'Motion Sensor' + | 'Contact Sensor' + | 'Ceiling Light' + | 'Ceiling Light Pro' + | 'Strip Light' + | 'Color Bulb' + | 'Robot Vacuum Cleaner S1' + | 'Robot Vacuum Cleaner S1 Plus' + | 'Robot Vacuum Cleaner K10 Plus' + | 'Humidifier' + | 'Humidifier 2' + | 'Blind Tilt' + | 'Hub 2' + | 'Hub Mini' + | 'Hub Plus' + | 'Remote' + | 'Battery Circulator Fan' + | 'Air Purifier' + | 'Air Purifier Table' + | 'Water Leak Detector' + | 'Presence Sensor' + | 'Relay Switch 1PM' + | 'Relay Switch 1' + | 'K10+ Pro Combo' + +/** + * Virtual/Infrared device types + */ +export type VirtualDeviceType + = | 'Air Conditioner' + | 'TV' + | 'Light' + | 'IPTV/Streamer' + | 'Set Top Box' + | 'DVD' + | 'Fan' + | 'Projector' + | 'Camera' + | 'Air Purifier' + | 'Speaker' + | 'Water Heater' + | 'Vacuum Cleaner' + | 'Others' diff --git a/src/types/ble-guards.test.ts b/src/types/ble-guards.test.ts deleted file mode 100644 index db2a0ec4..00000000 --- a/src/types/ble-guards.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { ceilingLightServiceData, colorBulbServiceData, meterServiceData } from './ble' - -import { describe, expect, it } from 'vitest' - -import { SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '../device' -import { isServiceDataOfModel } from './ble-guards' - -describe('ble service data guards', () => { - it('identifies colorBulbServiceData correctly', () => { - const sample: colorBulbServiceData = { - model: SwitchBotBLEModel.ColorBulb, - modelName: SwitchBotBLEModelName.ColorBulb, - modelFriendlyName: SwitchBotBLEModelFriendlyName.ColorBulb, - color_temperature: 3000, - power: true, - state: false, - red: 255, - green: 200, - blue: 150, - brightness: 50, - delay: 0, - preset: 1, - color_mode: 0, - speed: 10, - loop_index: 0, - } - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.ColorBulb)).toBe(true) - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.CeilingLight)).toBe(false) - }) - - it('identifies ceilingLightServiceData correctly', () => { - const sample: ceilingLightServiceData = { - model: SwitchBotBLEModel.CeilingLight, - modelName: SwitchBotBLEModelName.CeilingLight, - modelFriendlyName: SwitchBotBLEModelFriendlyName.CeilingLight, - color_temperature: 3500, - power: false, - state: true, - red: 100, - green: 150, - blue: 200, - brightness: 75, - delay: 5, - preset: 2, - color_mode: 1, - speed: 5, - loop_index: 1, - } - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.CeilingLight)).toBe(true) - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.Meter)).toBe(false) - }) - - it('identifies meterServiceData correctly', () => { - const sample: meterServiceData = { - model: SwitchBotBLEModel.Meter, - modelName: SwitchBotBLEModelName.Meter, - modelFriendlyName: SwitchBotBLEModelFriendlyName.Meter, - celsius: 22.5, - fahrenheit: 72.5, - fahrenheit_mode: false, - humidity: 45, - battery: 90, - } - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.Meter)).toBe(true) - expect(isServiceDataOfModel(sample, SwitchBotBLEModel.ColorBulb)).toBe(false) - }) -}) diff --git a/src/types/ble-guards.ts b/src/types/ble-guards.ts deleted file mode 100644 index b4635d74..00000000 --- a/src/types/ble-guards.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { SwitchBotBLEModel } from '../device' -import type { BLEDeviceServiceData } from './ble.js' - -/** - * Generic type guard for BLE device service data by model. - * @param data The BLE service data object. - * @param model The SwitchBotBLEModel enum to check against. - * @returns True if data.model matches, and narrows to the specific service data type. - */ -export function isServiceDataOfModel( - data: BLEDeviceServiceData, - model: M, -): data is Extract { - return data.model === model -} diff --git a/src/types/ble.ts b/src/types/ble.ts index 1c686722..737d1777 100644 --- a/src/types/ble.ts +++ b/src/types/ble.ts @@ -1,457 +1,337 @@ -/* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. * - * bledevicestatus.ts: @switchbot/homebridge-switchbot platform class. + * types/ble.ts: SwitchBot v4.0.0 - BLE Type Definitions */ -import type { MacAddress, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '../device.js' -/** - * BLE discovery and wait methods for SwitchBot devices. - */ -export interface SwitchBotScanner { - /** Discover BLE devices based on filter criteria */ - discover: (args: { duration?: number, model: string, quick: boolean, id?: MacAddress }) => Promise - /** Wait for given milliseconds */ - wait: (ms: number) => void -} +import type { Buffer } from 'node:buffer' /** - * Common service data across BLE devices. + * BLE Service Data for various SwitchBot devices */ -interface BLEServiceData { - model: SwitchBotBLEModel - modelName: SwitchBotBLEModelName - modelFriendlyName: SwitchBotBLEModelFriendlyName -} -/** - * Base interface for color-controllable devices. - */ -export interface ColorLightServiceDataBase extends BLEServiceData { - color_temperature: number - power: boolean - state: boolean - red: number - green: number - blue: number - brightness: number - delay: number - preset: number - color_mode: number - speed: number - loop_index: number +export interface BLEServiceData { + /** Device model */ + model: string + /** Model name string */ + modelName: string + /** Battery level (0-100) */ + battery?: number + /** Raw service data buffer */ + rawData?: Buffer + /** Parsed on/off state where available */ + state?: boolean + /** Parsed mode where available */ + mode?: 'press' | 'switch' | 'customize' | 'auto' | 'manual' | 'sleep' + /** Parsed movement state where available */ + inMotion?: boolean + /** Parsed lock state where available */ + lockState?: 'locked' | 'unlocked' | 'jammed' + /** Parsed lock raw status value where available */ + status?: number + /** Parsed door-open flag where available */ + doorOpen?: boolean + /** Parsed sequence number where available */ + sequenceNumber?: number + /** Parsed relay channel 2 state where available */ + channel2State?: boolean + /** Allow model-specific parser extensions */ + [key: string]: unknown } /** - * Base interface for temperature-humidity meter devices. + * Bot (WoHand) BLE Service Data */ -export interface TemperatureServiceDataBase extends BLEServiceData { - celsius: number - fahrenheit: number - fahrenheit_mode: boolean - humidity: number +export interface BotServiceData extends BLEServiceData { + mode: 'press' | 'switch' | 'customize' + state: boolean battery: number } /** - * Base interface for mini plug devices (US/JP share same schema). + * Curtain BLE Service Data */ -export interface PlugMiniServiceDataBase extends BLEServiceData { - state: string - delay: boolean - timer: boolean - syncUtcTime: boolean - wifiRssi: number - overload: boolean - currentPower: number +export interface CurtainServiceData extends BLEServiceData { + calibration: boolean + battery: number + position: number + lightLevel: number + deviceChain?: number } /** - * Base interface for lock-style devices. + * Lock BLE Service Data */ -export interface LockBaseServiceData extends BLEServiceData { +export interface LockServiceData extends BLEServiceData { battery: number calibration: boolean - status: string - update_from_secondary_lock: boolean - door_open: boolean - double_lock_mode: boolean - unclosed_alarm: boolean - unlocked_alarm: boolean - auto_lock_paused: boolean - night_latch: boolean + status: number + doorOpen: boolean + lockState: 'locked' | 'unlocked' | 'jammed' + autoLockDelay?: number } -export type botServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Bot - modelName: SwitchBotBLEModelName.Bot - modelFriendlyName: SwitchBotBLEModelFriendlyName.Bot - mode: boolean - state: boolean +/** + * Meter BLE Service Data + */ +export interface MeterServiceData extends BLEServiceData { + temperature: number + fahrenheit: boolean + humidity: number battery: number } -export type colorBulbServiceData = ColorLightServiceDataBase & { - model: SwitchBotBLEModel.ColorBulb - modelName: SwitchBotBLEModelName.ColorBulb - modelFriendlyName: SwitchBotBLEModelFriendlyName.ColorBulb -} - -export type contactSensorServiceData = BLEServiceData & { - model: SwitchBotBLEModel.ContactSensor - modelName: SwitchBotBLEModelName.ContactSensor - modelFriendlyName: SwitchBotBLEModelFriendlyName.ContactSensor +/** + * Contact Sensor BLE Service Data + */ +export interface ContactServiceData extends BLEServiceData { movement: boolean - tested: boolean - battery: number - contact_open: boolean - contact_timeout: boolean - lightLevel: string - button_count: number - doorState: string -} - -export type curtainServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Curtain - modelName: SwitchBotBLEModelName.Curtain - modelFriendlyName: SwitchBotBLEModelFriendlyName.Curtain - calibration: boolean - battery: number - inMotion: boolean - position: number - lightLevel: number - deviceChain: number -} - -export type curtain3ServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Curtain3 - modelName: SwitchBotBLEModelName.Curtain3 - modelFriendlyName: SwitchBotBLEModelFriendlyName.Curtain3 - calibration: boolean + position: 'open' | 'closed' | 'timeout' battery: number - inMotion: boolean - position: number - lightLevel: number - deviceChain: number -} - -export type stripLightServiceData = ColorLightServiceDataBase & { - model: SwitchBotBLEModel.StripLight - modelName: SwitchBotBLEModelName.StripLight - modelFriendlyName: SwitchBotBLEModelFriendlyName.StripLight -} - -export type lockServiceData = LockBaseServiceData & { - model: SwitchBotBLEModel.Lock - modelName: SwitchBotBLEModelName.Lock - modelFriendlyName: SwitchBotBLEModelFriendlyName.Lock -} - -export type lockProServiceData = LockBaseServiceData & { - model: SwitchBotBLEModel.LockPro - modelName: SwitchBotBLEModelName.LockPro - modelFriendlyName: SwitchBotBLEModelFriendlyName.LockPro -} - -export type meterServiceData = TemperatureServiceDataBase & { - model: SwitchBotBLEModel.Meter - modelName: SwitchBotBLEModelName.Meter - modelFriendlyName: SwitchBotBLEModelFriendlyName.Meter -} - -export type meterPlusServiceData = TemperatureServiceDataBase & { - model: SwitchBotBLEModel.MeterPlus - modelName: SwitchBotBLEModelName.MeterPlus - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPlus + lightLevel: 'bright' | 'dim' | 'dark' } -export type meterProServiceData = TemperatureServiceDataBase & { - model: SwitchBotBLEModel.MeterPro - modelName: SwitchBotBLEModelName.MeterPro - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPro -} - -export type meterProCO2ServiceData = TemperatureServiceDataBase & { - model: SwitchBotBLEModel.MeterProCO2 - modelName: SwitchBotBLEModelName.MeterProCO2 - modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterProCO2 - co2: number -} - -export type outdoorMeterServiceData = TemperatureServiceDataBase & { - model: SwitchBotBLEModel.OutdoorMeter - modelName: SwitchBotBLEModelName.OutdoorMeter - modelFriendlyName: SwitchBotBLEModelFriendlyName.OutdoorMeter -} - -export type motionSensorServiceData = BLEServiceData & { - model: SwitchBotBLEModel.MotionSensor - modelName: SwitchBotBLEModelName.MotionSensor - modelFriendlyName: SwitchBotBLEModelFriendlyName.MotionSensor - tested: boolean +/** + * Motion Sensor BLE Service Data + */ +export interface MotionServiceData extends BLEServiceData { movement: boolean battery: number - led: number - iot: number - sense_distance: number - lightLevel: string - is_light: boolean -} -export type presenceSensorServiceData = BLEServiceData & { - model: SwitchBotBLEModel.PresenceSensor - modelName: SwitchBotBLEModelName.PresenceSensor - modelFriendlyName: SwitchBotBLEModelFriendlyName.PresenceSensor - sequenceNumber: number - adaptiveState: boolean - motionDetected: boolean - batteryRange: string - triggerFlag: number - ledState: boolean - lightLevel: number - battery?: number -} - -export type plugMiniUSServiceData = PlugMiniServiceDataBase & { - model: SwitchBotBLEModel.PlugMiniUS - modelName: SwitchBotBLEModelName.PlugMini - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini -} - -export type plugMiniJPServiceData = PlugMiniServiceDataBase & { - model: SwitchBotBLEModel.PlugMiniJP - modelName: SwitchBotBLEModelName.PlugMini - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini -} - -export type plugMiniEUServiceData = PlugMiniServiceDataBase & { - model: SwitchBotBLEModel.PlugMiniEU - modelName: SwitchBotBLEModelName.PlugMini - modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini -} - -export type blindTiltServiceData = BLEServiceData & { - model: SwitchBotBLEModel.BlindTilt - modelName: SwitchBotBLEModelName.BlindTilt - modelFriendlyName: SwitchBotBLEModelFriendlyName.BlindTilt - calibration: boolean - battery: number - inMotion: boolean - tilt: number - lightLevel: number - sequenceNumber: number + lightLevel: 'bright' | 'dim' | 'dark' + iotButton?: boolean } -export type ceilingLightServiceData = BLEServiceData & { - model: SwitchBotBLEModel.CeilingLight - modelName: SwitchBotBLEModelName.CeilingLight - modelFriendlyName: SwitchBotBLEModelFriendlyName.CeilingLight - color_temperature: number - power: boolean +/** + * Plug BLE Service Data + */ +export interface PlugServiceData extends BLEServiceData { state: boolean - red: number - green: number - blue: number - brightness: number - delay: number - preset: number - color_mode: number - speed: number - loop_index: number + delay: boolean + timer: boolean + syncUtcTime: boolean + wifiRssi: number + overload: boolean + currentPower: number } -export type ceilingLightProServiceData = BLEServiceData & { - model: SwitchBotBLEModel.CeilingLightPro - modelName: SwitchBotBLEModelName.CeilingLightPro - modelFriendlyName: SwitchBotBLEModelFriendlyName.CeilingLightPro - color_temperature: number - power: boolean +/** + * Bulb BLE Service Data + */ +export interface BulbServiceData extends BLEServiceData { state: boolean - red: number - green: number - blue: number brightness: number - delay: number - preset: number - color_mode: number - speed: number - loop_index: number -} - -export type hub2ServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Hub2 - modelName: SwitchBotBLEModelName.Hub2 - modelFriendlyName: SwitchBotBLEModelFriendlyName.Hub2 - celsius: number - fahrenheit: number - fahrenheit_mode: boolean - humidity: number - lightLevel: number + red?: number + green?: number + blue?: number + colorTemperature?: number + delay?: boolean + preset?: boolean + colorMode?: boolean } -export type hub3ServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Hub3 - modelName: SwitchBotBLEModelName.Hub3 - modelFriendlyName: SwitchBotBLEModelFriendlyName.Hub3 - celsius: number - fahrenheit: number - fahrenheit_mode: boolean - humidity: number - lightLevel: number -} +/** + * Strip Light BLE Service Data + */ +export interface StripServiceData extends BulbServiceData {} -export type batteryCirculatorFanServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Unknown - modelName: SwitchBotBLEModelName.Unknown - modelFriendlyName: SwitchBotBLEModelFriendlyName.Unknown - state: string - fanSpeed: number -} +/** + * Ceiling Light BLE Service Data + */ +export interface CeilingLightServiceData extends BulbServiceData {} -export type waterLeakDetectorServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Leak - modelName: SwitchBotBLEModelName.Leak - modelFriendlyName: SwitchBotBLEModelFriendlyName.Leak - leak: boolean - tampered: boolean +/** + * Blind Tilt BLE Service Data + */ +export interface BlindTiltServiceData extends BLEServiceData { + calibration: boolean battery: number - low_battery: boolean + position: number + lightLevel: number + inMotion: boolean } -export type humidifierServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Humidifier - modelName: SwitchBotBLEModelName.Humidifier - modelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier +/** + * Humidifier BLE Service Data + */ +export interface HumidifierServiceData extends BLEServiceData { onState: boolean autoMode: boolean percentage: number - humidity: number + lackWater: boolean } -export type humidifier2ServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Humidifier2 - modelName: SwitchBotBLEModelName.Humidifier2 - modelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier2 - onState: boolean - autoMode: boolean - percentage: number - humidity: number - childLock: boolean - overHumidifyProtection: boolean - tankRemoved: boolean - tiltedAlert: boolean - filterMissing: boolean +/** + * Air Purifier BLE Service Data + */ +export interface AirPurifierServiceData extends BLEServiceData { + state: boolean + fanSpeed: number + mode: 'auto' | 'manual' | 'sleep' + pm25?: number +} + +/** + * Hub BLE Service Data + */ +export interface HubServiceData extends BLEServiceData { temperature: number - filterRunTime: number - filterAlert: boolean - waterLevel: number + fahrenheit: boolean + humidity: number + lightLevel: number } -export type robotVacuumCleanerServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Unknown - modelName: SwitchBotBLEModelName.Unknown - modelFriendlyName: SwitchBotBLEModelFriendlyName.Unknown - state: string +/** + * Leak Detector BLE Service Data + */ +export interface LeakServiceData extends BLEServiceData { + waterLeakDetected: boolean battery: number } -export type keypadDetectorServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Keypad - modelName: SwitchBotBLEModelName.Keypad - modelFriendlyName: SwitchBotBLEModelFriendlyName.Keypad - event: boolean - tampered: boolean +/** + * Presence Sensor BLE Service Data + */ +export interface PresenceServiceData extends BLEServiceData { + movement: boolean battery: number - low_battery: boolean + lightLevel: 'bright' | 'dim' | 'dark' } -export type relaySwitch1ServiceData = BLEServiceData & { - model: SwitchBotBLEModel.RelaySwitch1 - modelName: SwitchBotBLEModelName.RelaySwitch1 - modelFriendlyName: SwitchBotBLEModelFriendlyName.RelaySwitch1 - mode: boolean +/** + * Relay Switch BLE Service Data + */ +export interface RelaySwitchServiceData extends BLEServiceData { state: boolean - sequence_number: number + power?: number + voltage?: number + current?: number } -export type relaySwitch1PMServiceData = BLEServiceData & { - model: SwitchBotBLEModel.RelaySwitch1PM - modelName: SwitchBotBLEModelName.RelaySwitch1PM - modelFriendlyName: SwitchBotBLEModelFriendlyName.RelaySwitch1PM - mode: boolean - state: boolean - sequence_number: number - power: number - voltage: number - current: number +/** + * BLE Device Advertisement + */ +export interface BLEAdvertisement { + id: string + address?: string + isAddressable: boolean + rssi: number + serviceData: BLEServiceData + /** Raw BLE advertisement data (entire buffer) */ + rawAdvData?: Buffer + /** True if advertisement is encrypted */ + isEncrypted?: boolean + /** User-friendly model name (e.g., "WoHand") */ + modelFriendlyName?: string } -export type remoteServiceData = BLEServiceData & { - model: SwitchBotBLEModel.Remote - modelName: SwitchBotBLEModelName.Remote - modelFriendlyName: SwitchBotBLEModelFriendlyName.Remote - battery: number +/** + * BLE Scanner options + */ +export interface BLEScanOptions { + /** Scan duration in milliseconds */ + duration?: number + /** Filter by specific MAC addresses */ + macs?: string[] + /** Filter by device model */ + model?: string + /** Active scanning (default: true) */ + active?: boolean } -export type airPurifierServiceData = BLEServiceData & { - model: SwitchBotBLEModel.AirPurifier - modelName: SwitchBotBLEModelName.AirPurifier - modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifier - isOn: boolean - mode: string | null - isAqiValid: boolean - child_lock: boolean - speed: number - aqi_level: string - filter_element_working_time: number - err_code: number - sequence_number: number +/** + * SwitchBot BLE Model identifiers + */ +export enum SwitchBotBLEModel { + Bot = 'H', + Curtain = 'c', + Curtain3 = '{', + Plug = 'g', + PlugMiniUS = 'j', + // eslint-disable-next-line ts/no-duplicate-enum-values + PlugMiniJP = 'j', + Meter = 'T', + MeterPlus = 'i', + MeterPro = 'o', + MeterProCO2 = 'w', + OutdoorMeter = 'n', + // eslint-disable-next-line ts/no-duplicate-enum-values + Lock = 'o', + LockPro = '\x11', + Keypad = 'k', + KeypadTouch = '\x0B', + MotionSensor = 's', + ContactSensor = 'd', + CeilingLight = 'q', + CeilingLightPro = 'r', + StripLight = 'p', + ColorBulb = 'u', + RobotVacuumCleanerS1 = '\x0A', + RobotVacuumCleanerS1Plus = '\x0C', + RobotVacuumCleanerK10Plus = '\x0F', + Humidifier = 'e', + Humidifier2 = '\x07', + BlindTilt = 'x', + Hub2 = '\x01', + Hub3 = '\x02', + Remote = '\x05', + BatteryCirculatorFan = '\x04', + AirPurifier = '\x08', + AirPurifierTable = '\x09', + WaterLeakDetector = 'y', + PresenceSensor = '\x06', + RelaySwitch1PM = '\x0D', + RelaySwitch1 = '\x0E', + K10ProComboK10Pro = '\x10', } -export type airPurifierTableServiceData = BLEServiceData & { - model: SwitchBotBLEModel.AirPurifierTable - modelName: SwitchBotBLEModelName.AirPurifierTable - modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifierTable - isOn: boolean - mode: string | null - isAqiValid: boolean - child_lock: boolean - speed: number - aqi_level: string - filter_element_working_time: number - err_code: number - sequence_number: number +/** + * SwitchBot BLE Model Names + */ +export enum SwitchBotBLEModelName { + Bot = 'WoHand', + Curtain = 'WoCurtain', + Curtain3 = 'WoCurtain3', + Plug = 'WoPlugUS', + PlugMiniUS = 'WoPlugMiniUS', + PlugMiniJP = 'WoPlugMiniJP', + Meter = 'WoSensorTH', + MeterPlus = 'WoSensorTHPlus', + MeterPro = 'WoSensorTHPro', + MeterProCO2 = 'WoSensorTHProCO2', + OutdoorMeter = 'WoIOSensorTH', + Lock = 'WoSmartLock', + LockPro = 'WoSmartLockPro', + Keypad = 'WoKeypad', + KeypadTouch = 'WoKeypadTouch', + MotionSensor = 'WoMotion', + ContactSensor = 'WoContact', + CeilingLight = 'WoCeilingLight', + CeilingLightPro = 'WoCeilingLightPro', + StripLight = 'WoStrip', + ColorBulb = 'WoBulb', + RobotVacuumCleanerS1 = 'WoVacS1', + RobotVacuumCleanerS1Plus = 'WoVacS1Plus', + RobotVacuumCleanerK10Plus = 'WoVacK10Plus', + Humidifier = 'WoHumi', + Humidifier2 = 'WoHumi2', + BlindTilt = 'WoBlindTilt', + Hub2 = 'WoHub2', + Hub3 = 'WoHub3', + Remote = 'WoRemote', + BatteryCirculatorFan = 'WoCirculatorFan', + AirPurifier = 'WoAirPurifier', + AirPurifierTable = 'WoAirPurifierTable', + WaterLeakDetector = 'WoLeak', + PresenceSensor = 'WoPresence', + RelaySwitch1PM = 'WoRelaySwitch1PM', + RelaySwitch1 = 'WoRelaySwitch1', + K10ProComboK10Pro = 'WoVacK10ProCombo', } -export type BLEDeviceServiceData - = | airPurifierServiceData - | airPurifierTableServiceData - | batteryCirculatorFanServiceData - | blindTiltServiceData - | botServiceData - | ceilingLightServiceData - | ceilingLightProServiceData - | colorBulbServiceData - | contactSensorServiceData - | curtain3ServiceData - | curtainServiceData - | hub2ServiceData - | hub3ServiceData - | keypadDetectorServiceData - | lockProServiceData - | lockServiceData - | meterPlusServiceData - | meterProCO2ServiceData - | meterProServiceData - | meterServiceData - | motionSensorServiceData - | outdoorMeterServiceData - | presenceSensorServiceData - | plugMiniJPServiceData - | plugMiniUSServiceData - | plugMiniEUServiceData - | relaySwitch1PMServiceData - | relaySwitch1ServiceData - | remoteServiceData - | robotVacuumCleanerServiceData - | stripLightServiceData - | waterLeakDetectorServiceData - | humidifier2ServiceData - | humidifierServiceData +/** + * Noble types (for BLE communication) + */ +export interface NobleTypes { + Peripheral?: any + Service?: any + Characteristic?: any + Noble?: any +} diff --git a/src/types/device.ts b/src/types/device.ts new file mode 100644 index 00000000..c3546feb --- /dev/null +++ b/src/types/device.ts @@ -0,0 +1,317 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * types/device.ts: SwitchBot v4.0.0 - Device-Specific Type Definitions + */ + +import type { Buffer } from 'node:buffer' + +import type { DeviceStatus } from './index.js' + +export type { DeviceStatus } + +/** + * Bot (WoHand) specific types + */ +export interface BotStatus extends DeviceStatus { + power: 'on' | 'off' + mode?: 'press' | 'switch' | 'customize' +} + +export interface BotCommands { + turnOn: () => Promise + turnOff: () => Promise + press: () => Promise + setMode?: (mode: 'press' | 'switch') => Promise + setLongPress?: (duration: number) => Promise + handUp?: () => Promise + handDown?: () => Promise +} + +/** + * Curtain (WoCurtain) specific types + */ +export interface CurtainStatus extends DeviceStatus { + position: number // 0-100 + calibrated?: boolean + moving?: boolean + direction?: 'opening' | 'closing' + slidePosition?: number +} + +/** + * Curtain extended info (device chain, grouped status) + */ +export interface CurtainExtendedInfo { + deviceChain?: { + masterDevice: string + slaveDevices: string[] + } + groupStatus?: { + position: number + calibrated: boolean + moving: boolean + } +} + +export interface CurtainCommands { + open: (speed?: number) => Promise + close: (speed?: number) => Promise + pause: () => Promise + setPosition: (position: number, speed?: number) => Promise + getExtendedInfo?: () => Promise + sendCommandSequence?: (commands: Array<() => Promise>) => Promise + sendMultipleCommands?: (commands: Array<() => Promise>) => Promise +} + +/** + * Lock (WoSmartLock) specific types + */ +export interface LockStatus extends DeviceStatus { + lockState: 'locked' | 'unlocked' | 'jammed' + doorState?: 'opened' | 'closed' + calibrated?: boolean +} + +export interface LockCommands { + lock: () => Promise + unlock: () => Promise + unlockWithoutUnlatch?: () => Promise + getLockInfo?: () => Promise> + onLockNotification?: (handler: (payload: Buffer) => void) => Promise + offLockNotification?: (handler: (payload: Buffer) => void) => void +} + +/** + * Meter (Temperature/Humidity) specific types + */ +export interface MeterStatus extends DeviceStatus { + temperature: number + humidity: number + temperatureScale?: 'c' | 'f' +} + +/** + * Contact Sensor specific types + */ +export interface ContactStatus extends DeviceStatus { + openState: 'open' | 'closed' | 'timeout' + moveDetected?: boolean + brightness?: 'bright' | 'dim' | 'dark' +} + +/** + * Motion Sensor specific types + */ +export interface MotionStatus extends DeviceStatus { + moveDetected: boolean + brightness?: 'bright' | 'dim' | 'dark' +} + +/** + * Plug specific types + */ +export interface PlugStatus extends DeviceStatus { + power: 'on' | 'off' + voltage?: number + electricCurrent?: number + electricityOfDay?: number +} + +export interface PlugCommands { + turnOn: () => Promise + turnOff: () => Promise + toggle: () => Promise +} + +/** + * Bulb/Light specific types + */ +export interface BulbStatus extends DeviceStatus { + power: 'on' | 'off' + brightness?: number // 0-100 + colorTemperature?: number // Kelvin + color?: { r: number, g: number, b: number } +} + +export interface BulbCommands { + turnOn: () => Promise + turnOff: () => Promise + setBrightness: (brightness: number) => Promise + setColorTemperature: (temperature: number) => Promise + setColor: (red: number, green: number, blue: number) => Promise + setEffect?: (effectName: string, speed?: number) => Promise + setColorTemp?: (minTemp: number, maxTemp: number, temp: number) => Promise + sendCommandSequence?: (commands: Array<() => Promise>) => Promise + sendMultipleCommands?: (commands: Array<() => Promise>) => Promise +} + +/** + * RGBIC Bulb specific types (segmented/multi-zone color control) + */ +export interface RGBICBulbStatus extends BulbStatus {} + +export interface RGBICBulbCommands extends BulbCommands { + setSegmentColor?: (segmentId: number, red: number, green: number, blue: number) => Promise + setSegmentEffect?: (segmentId: number, effectName: string, speed?: number) => Promise +} + +/** + * Strip Light specific types + */ +export interface StripStatus extends BulbStatus {} +export interface StripCommands extends BulbCommands {} + +/** + * Ceiling Light specific types + */ +export interface CeilingLightStatus extends BulbStatus {} +export interface CeilingLightCommands extends BulbCommands {} + +/** + * Blind Tilt specific types + */ +export interface BlindTiltStatus extends DeviceStatus { + position: number // 0-100 + direction?: 'opening' | 'closing' + moving?: boolean + calibrated?: boolean +} + +export interface BlindTiltCommands { + open: () => Promise + close: () => Promise + closeUp: () => Promise + closeDown: () => Promise + pause: () => Promise + setPosition: (position: number) => Promise +} + +/** + * Humidifier specific types + */ +export interface HumidifierStatus extends DeviceStatus { + power: 'on' | 'off' + humidity?: number + mode?: 'auto' | 'manual' + nebulizationEfficiency?: number + lackWater?: boolean + temperature?: number +} + +export interface HumidifierCommands { + turnOn: () => Promise + turnOff: () => Promise + setMode: (mode: 'auto' | 'manual') => Promise + setEfficiency: (level: number) => Promise + setLevel?: (level: number) => Promise + setAuto?: () => Promise + setManual?: () => Promise + getTargetLevel?: () => Promise +} + +/** + * Air Purifier specific types + */ +export interface AirPurifierStatus extends DeviceStatus { + power: 'on' | 'off' + fanSpeed?: number // 1-4 + mode?: 'auto' | 'manual' | 'sleep' + pm25?: number + airQuality?: 'excellent' | 'good' | 'fair' | 'poor' +} + +export interface AirPurifierCommands { + turnOn: () => Promise + turnOff: () => Promise + setMode: (mode: 'auto' | 'manual' | 'sleep') => Promise + setFanSpeed: (speed: number) => Promise + setPresetMode?: (mode: 'level_1' | 'level_2' | 'level_3' | 'auto' | 'sleep' | 'pet') => Promise +} + +/** + * Vacuum specific types + */ +export interface VacuumStatus extends DeviceStatus { + battery?: number + workStatus?: number + dustbinBound?: boolean + dustbinConnected?: boolean + networkConnected?: boolean +} + +export interface VacuumCommands { + cleanUp: (protocolVersion: number) => Promise + returnToDock: (protocolVersion: number) => Promise + getBattery?: () => number | undefined + getWorkStatus?: () => number | undefined + getDustbinBoundStatus?: () => boolean | undefined + getDustbinConnectedStatus?: () => boolean | undefined + getNetworkConnectedStatus?: () => boolean | undefined +} + +/** + * Hub specific types + */ +export interface HubStatus extends DeviceStatus { + temperature?: number + humidity?: number + lightLevel?: number +} + +/** + * Leak Detector specific types + */ +export interface LeakStatus extends DeviceStatus { + waterLeakDetected: boolean +} + +/** + * Presence Sensor specific types + */ +export interface PresenceStatus extends DeviceStatus { + moveDetected: boolean + brightness?: 'bright' | 'dim' | 'dark' +} + +/** + * Relay Switch specific types + */ +export interface RelaySwitchStatus extends DeviceStatus { + power: 'on' | 'off' + voltage?: number + electricCurrent?: number + electricityOfDay?: number +} + +export interface RelaySwitchCommands { + turnOn: () => Promise + turnOff: () => Promise + toggle: () => Promise + /** + * Get current time and start time for energy tracking (Task 5.4) + */ + getCurrentTimeAndStartTime?: () => Promise<{ currentTime: Date, startTime: Date, [key: string]: any }> +} + +/** + * Relay Switch 2PM specific types (with channel-specific control) + */ +export interface RelaySwitchChannelCommands extends RelaySwitchCommands { + setChannel1?: (state: boolean) => Promise + setChannel2?: (state: boolean) => Promise +} + +/** + * Keypad specific types + */ +export interface KeypadStatus extends DeviceStatus { + // Keypad is typically used for lock control + lockState?: 'locked' | 'unlocked' +} + +/** + * Remote specific types + */ +export interface RemoteStatus extends DeviceStatus { + // Remote doesn't have controllable status, mainly for battery info +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 00000000..5bdd829c --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,166 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * types/index.ts: SwitchBot v4.0.0 - Core Type Definitions + */ + +/** + * Log levels for debugging and diagnostics + */ +export enum LogLevel { + NONE = 0, + ERROR = 1, + WARN = 2, + INFO = 3, + DEBUG = 4, +} + +/** + * Device connection type + */ +export type ConnectionType = 'ble' | 'api' | 'hybrid' + +/** + * SwitchBot configuration options + */ +export interface SwitchBotConfig { + /** OpenAPI token (optional - required for API/Hybrid mode) */ + token?: string + /** OpenAPI secret (optional - required for API/Hybrid mode) */ + secret?: string + /** OpenAPI base URL (optional - defaults to official API) */ + baseURL?: string + /** Enable BLE scanning (default: true on Linux) */ + enableBLE?: boolean + /** BLE scan timeout in milliseconds (default: 10000) */ + scanTimeout?: number + /** Enable BLE to API fallback on errors (default: true) */ + enableFallback?: boolean + /** Log level (default: WARN) */ + logLevel?: LogLevel + /** Noble instance (optional - for custom BLE configuration) */ + noble?: any + /** Enable intelligent connection selection based on success history (default: true) */ + enableConnectionIntelligence?: boolean + /** Enable circuit breaker for connection reliability (default: true) */ + enableCircuitBreaker?: boolean + /** Enable automatic retry with exponential backoff (default: true) */ + enableRetry?: boolean + /** Maximum retry attempts per command (default: 3) */ + maxRetryAttempts?: number + /** Initial retry delay in milliseconds (default: 100) */ + retryInitialDelayMs?: number + /** Maximum retry delay in milliseconds (default: 5000) */ + retryMaxDelayMs?: number + /** Enable detailed error reporting in command results (default: false) */ + detailedErrors?: boolean + /** Custom logger instance (optional) */ + logger?: { + error: (message: string, ...args: any[]) => void + warn: (message: string, ...args: any[]) => void + info: (message: string, ...args: any[]) => void + debug: (message: string, ...args: any[]) => void + } + /** Additional custom options can be added as needed */ + [key: string]: any + /** Internal options for testing and advanced use (not part of public API) */ + _internal?: { + /** Force use of BLE for testing (overrides intelligent selection) */ + forceBLE?: boolean + /** Force use of API for testing (overrides intelligent selection) */ + forceAPI?: boolean + } +} + +/** + * Device discovery options + */ +export interface DiscoveryOptions { + /** Scan for BLE devices (default: true if BLE enabled) */ + scanBLE?: boolean + /** Fetch devices from API (default: true if credentials provided) */ + fetchAPI?: boolean + /** Discovery timeout in milliseconds (default: 10000) */ + timeout?: number + /** Filter by device ID (optional) */ + deviceId?: string + /** Filter by device MAC address (optional) */ + mac?: string + /** Filter by device type (optional) */ + deviceType?: string +} + +/** + * Base device information + */ +export interface DeviceInfo { + /** Device ID */ + id: string + /** Device name */ + name: string + /** Device type (e.g., 'Bot', 'Curtain', 'Lock') */ + deviceType: string + /** Device model */ + model?: string + /** MAC address (for BLE devices) */ + mac?: string + /** BLE peripheral/advertisement ID (for ID-based lookups on macOS) */ + bleId?: string + /** Available connection types */ + connectionTypes: ConnectionType[] + /** Current active connection type */ + activeConnection?: ConnectionType + /** Hub device ID (if device is controlled through a hub) */ + hubDeviceId?: string + /** Battery level (0-100) */ + battery?: number + /** RSSI signal strength (for BLE) */ + rssi?: number + /** Last parsed BLE advertisement service data */ + bleServiceData?: Record + /** Optional BLE encryption key as hex (16 bytes / 32 hex chars) */ + encryptionKey?: string + /** Optional BLE encryption IV as hex */ + encryptionIV?: string + /** Optional BLE encryption mode */ + encryptionMode?: 'auto' | 'ctr' | 'gcm' + /** Firmware version */ + version?: string + /** CloudService enabled in OpenAPI */ + cloudServiceEnabled?: boolean +} + +/** + * Device command result + */ +export interface CommandResult { + /** Success status */ + success: boolean + /** Connection type used */ + connectionType: ConnectionType + /** Error message (if failed) */ + error?: string + /** Response data */ + data?: any + /** Whether API fallback was used */ + usedFallback?: boolean +} + +/** + * Device status (generic - specific devices extend this) + */ +export interface DeviceStatus { + /** Device ID */ + deviceId: string + /** Connection type used to retrieve status */ + connectionType: ConnectionType + /** Firmware version */ + version?: string + /** Battery level (0-100) */ + battery?: number + /** Last updated timestamp */ + updatedAt?: Date +} + +export * from './api.js' +export * from './ble.js' +export * from './device.js' diff --git a/src/types/openapi.ts b/src/types/openapi.ts deleted file mode 100644 index ca04f538..00000000 --- a/src/types/openapi.ts +++ /dev/null @@ -1,779 +0,0 @@ -/* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. - * - * openapi.ts: Aggregated types for SwitchBot OpenAPI and IR interfaces. - */ -export interface deviceList { - device: device[] -} - -export interface device { - deviceId: string - deviceName: string - deviceType: string - enableCloudService: boolean - hubDeviceId: string - version?: number -} - -export type bot = device - -export type curtain = device & { - curtainDevicesIds: string[] - calibrate: boolean - group: boolean - master: boolean - openDirection: string -} - -export type curtain3 = device & { - curtainDevicesIds: string[] - calibrate: boolean - group: boolean - master: boolean - openDirection?: string -} - -export type hub2 = device - -export type meter = device - -export type meterPlus = device - -export type meterPro = device - -export type outdoorMeter = device - -export type lock = device & { - group: boolean - master: boolean - groupName: string - lockDevicesIds: string[] -} - -export type lockPro = device & { - group: boolean - master: boolean - groupName: string - lockDevicesIds: string[] -} - -export type keypad = device & { - remoteType: string - lockDeviceId: string - keyList: keyList -} - -export type keypadTouch = device & { - remoteType: string - lockDeviceId: string - keyList: keyList -} - -interface keyList { - id: number - name: string - type: string - password: string - iv: string - status: string - createTime: number -} - -export type remote = device - -export type motionSensor = device - -export type presenceSensor = device - -export type contactSensor = device - -export type waterLeakDetector = device - -export type ceilingLight = device - -export type ceilingLightPro = device - -export type plug = device - -export type plugMini = device - -export type airPurifier = device - -export type airPurifierTable = device - -export type airPurifierVOC = device - -export type airPurifierTableVOC = device - -export type stripLight = device - -export type colorBulb = device - -export type robotVacuumCleanerS1 = device - -export type robotVacuumCleanerS1Plus = device - -export type floorCleaningRobotS10 = device - -export type humidifier = device - -export type IndoorCam = device - -export type pantiltCam = device - -export type pantiltCam2k = device - -export type blindTilt = device & { - blindTiltDevicesIds: string[] - calibrate: boolean - group: boolean - master: boolean - direction: string - slidePosition: number -} - -export type batteryCirculatorFan = device - -/** - * Allowed command types for device control. - */ -export type commandType = 'command' | 'customize' - -/** - * Request payload for controlling a device. - */ -export interface pushRequest { - command: string - parameter: string - commandType: commandType -} - -/** - * Body of a device push response. - */ -export interface pushResponseBody { - commandId: string -} - -/** - * Response from a device control (push) request. - */ -export interface pushResponse { - statusCode: number - body: pushResponseBody - message: string -} - -export interface bodyChange { - command: string - parameter: string - commandType: string -} - -// json response from SwitchBot API -export interface devices { - statusCode: number - message: string - body: body -} - -export interface body { - deviceList: device[] - infraredRemoteList: infraredRemoteList -} - -export interface deviceStatusRequest { - statusCode: number - message: string - body: deviceStatus -} - -export interface deviceStatus extends device { - // properties on all devices - deviceId: string - deviceType: string - hubDeviceId: string - version: number -}; - -export type botStatus = deviceStatus & { - power: string - battery: number - mode: 'pressMode' | 'switchMode' | 'customizeMode' -} - -export type curtainStatus = deviceStatus & { - calibrate: boolean - group: boolean - moving: boolean - battery: number - slidePosition: number - lightLevel?: 'bright' | 'dim' -} - -export type meterStatus = deviceStatus & { - temperature: number - battery: number - humidity: number -} - -export type meterPlusStatus = deviceStatus & { - temperature: number - battery: number - humidity: number -} - -export type meterProStatus = deviceStatus & { - temperature: number - battery: number - humidity: number - version: string -} - -export type meterProCO2Status = deviceStatus & { - temperature: number - battery: number - humidity: number - version: string - CO2: number -} - -export type outdoorMeterStatus = deviceStatus & { - battery: number - temperature: number - humidity: number -} - -export type lockStatus = deviceStatus & { - lockState: string - doorState: string - moveDetected: boolean - battery: number -} - -export type lockProStatus = deviceStatus & { - lockState: string - doorState: string - moveDetected: boolean - battery: number -} - -export type motionSensorStatus = deviceStatus & { - battery: number - moveDetected: boolean - brightness: 'bright' | 'dim' -} - -export type presenceSensorStatus = deviceStatus & { - battery: number - version: string - Detected: boolean - lightLevel: number // 1~20 -} - -export type contactSensorStatus = deviceStatus & { - battery: number - moveDetected: boolean - openState: 'open' | 'close' | 'timeOutNotClose' - brightness: 'bright' | 'dim' -} - -export type waterLeakDetectorStatus = deviceStatus & { - battery: number - status: 0 /* dry */ | 1 /* leak detected */ -} - -export type ceilingLightStatus = deviceStatus & { - power: boolean - brightness: number - colorTemperature: number -} - -export type ceilingLightProStatus = deviceStatus & { - power: boolean - brightness: number - colorTemperature: number -} - -export type plugStatus = deviceStatus & { - power: string - version: string -} - -export type plugMiniStatus = deviceStatus & { - voltage: Float64Array - weight: Float64Array - electricityOfDay: number - electricCurrent: Float64Array - power: string -} - -export type stripLightStatus = deviceStatus & { - power: string - brightness: number - color: string -} - -export type colorBulbStatus = deviceStatus & { - power: string - brightness: number - color: string - colorTemperature: number -} - -export type robotVacuumCleanerS1Status = deviceStatus & { - workingStatus: string - onlineStatus: string - battery: number -} - -export type robotVacuumCleanerS1PlusStatus = deviceStatus & { - workingStatus: string - onlineStatus: string - battery: number -} - -export type floorCleaningRobotS10Status = deviceStatus & { - workingStatus: string - onlineStatus: string - battery: number - waterBaseBattery: number - taskType: string -} - -export type humidifierStatus = deviceStatus & { - power: string - humidity: number - temperature: number - nebulizationEfficiency: number - auto: boolean - childLock: boolean - sound: boolean - lackWater: boolean -} - -export type humidifier2Status = deviceStatus & { - power: string - humidity: number - temperature: number - nebulizationEfficiency: number - auto: boolean - childLock: boolean - sound: boolean - lackWater: boolean -} - -export type blindTiltStatus = deviceStatus & { - calibrate: boolean - battery: number - direction: string - slidePosition: string - lightLevel?: 'bright' | 'dim' -} - -export type hub2Status = deviceStatus & { - temperature: number - lightLevel: number - humidity: number -} - -export type batteryCirculatorFanStatus = deviceStatus & { - mode: 'direct' | 'natural' | 'sleep' | 'baby' - version: string - battery: number - power: string - nightStatus: number - oscillation: string - verticalOscillation: string - chargingStatus: string - fanSpeed: number -} - -export type circulatorFanStatus = deviceStatus & { - mode: 'direct' | 'natural' | 'sleep' | 'baby' - version: string - power: string - nightStatus: number - oscillation: string - verticalOscillation: string - fanSpeed: number -} - -export type relaySwitch1Status = deviceStatus & { - switchStatus: 0 | 1 - version: string -} - -export type relaySwitch1PMStatus = deviceStatus & { - switchStatus: 0 | 1 - voltage: number - version: string - power: number - usedElectricity: number - electricCurrent: number -} - -export type airPurifierStatus = deviceStatus & { - power: string - mode: number - childLock: number - version: string -} - -export type airPurifierTableStatus = deviceStatus & { - power: string - mode: number - childLock: number - version: string -} - -export type airPurifierVOCStatus = deviceStatus & { - power: string - mode: number - childLock: number - version: string -} - -export type airPurifierTableVOCStatus = deviceStatus & { - power: string - mode: number - childLock: number - version: string -} - -export interface webhookRequest { - action: string - url: string - deviceList: string -} - -export interface setupWebhookResponse { - statusCode: number - body: object - message: string -} - -export interface queryWebhookResponse { - statusCode: number - body: WebhookDetail[] - message: string -} - -export interface WebhookDetail { - url: string - createTime: number - lastUpdateTime: number - deviceList: string - enable: boolean -} - -export interface updateWebhookResponse { - statusCode: number - body: object - message: string -} - -export interface deleteWebhookResponse { - statusCode: number - body: object - message: string -} - -interface deviceWebhook { - eventType: string - eventVersion: string - context: deviceWebhookContext -} - -export { deviceWebhook } - -export interface deviceWebhookContext { - // properties on all devices - deviceMac: string - deviceType: string - timeOfSample: number -} - -export type botWebhookContext = deviceWebhookContext & { - power: string // "on"or"off" - battery: number - deviceMode: 'pressMode' | 'switchMode' | 'customizeMode' -} - -export type curtainWebhookContext = deviceWebhookContext & { - calibrate: boolean - group: boolean - slidePosition: number // 0~100 - battery: number -} - -export type curtain3WebhookContext = deviceWebhookContext & { - calibrate: boolean - group: boolean - slidePosition: number // 0~100 - battery: number -} - -export type motionSensorWebhookContext = deviceWebhookContext & { - detectionState: 'NOT_DETECTED' | 'DETECTED' - battery: number // 0~100 -} - -export type presenceSensorWebhookContext = deviceWebhookContext & { - detectionState: 'NOT_DETECTED' | 'DETECTED' - battery: number // 0~100 - lightLevel: number // 1~20 -} - -export type contactSensorWebhookContext = deviceWebhookContext & { - detectionState: 'NOT_DETECTED' | 'DETECTED' - battery: number // 0~100 - doorMode: 'IN_DOOR' | 'OUT_DOOR' - brightness: 'dim' | 'bright' - openState: 'open' | 'close' | 'timeOutNotClose' -} - -export type waterLeakDetectorWebhookContext = deviceWebhookContext & { - detectionState: 0 | 1 - battery: number // 0~100 -} - -export type meterWebhookContext = deviceWebhookContext & { - temperature: number - battery: number // 0~100 - scale: 'CELSIUS' | 'FAHRENHEIT' - humidity: number -} - -export type meterPlusWebhookContext = deviceWebhookContext & { - temperature: number - battery: number // 0~100 - scale: 'CELSIUS' | 'FAHRENHEIT' - humidity: number -} - -export type meterProWebhookContext = deviceWebhookContext & { - temperature: number - battery: number // 0~100 - scale: 'CELSIUS' | 'FAHRENHEIT' - humidity: number -} - -export type meterProCO2WebhookContext = deviceWebhookContext & { - temperature: number - battery: number // 0~100 - scale: 'CELSIUS' | 'FAHRENHEIT' - humidity: number - CO2: number -} - -export type outdoorMeterWebhookContext = deviceWebhookContext & { - temperature: number - battery: number // 0~100 - scale: 'CELSIUS' | 'FAHRENHEIT' - humidity: number -} - -export type lockWebhookContext = deviceWebhookContext & { - lockState: 'UNLOCKED' | 'LOCKED' | 'JAMMED' - battery: number // 0~100 -} - -export type lockProWebhookContext = deviceWebhookContext & { - lockState: 'UNLOCKED' | 'LOCKED' | 'JAMMED' - battery: number // 0~100 -} - -export type indoorCameraWebhookContext = deviceWebhookContext & { - detectionState: 'DETECTED' -} - -export type panTiltCamWebhookContext = deviceWebhookContext & { - detectionState: 'DETECTED' -} - -export type colorBulbWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' - brightness: number - color: string // RGB 255:255:255 - colorTemperature: number // 2700~6500 -} - -export type stripLightWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' - brightness: number - color: string // RGB 255:255:255 -} - -export type plugWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' -} - -export type plugMiniUSWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' -} - -export type plugMiniJPWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' -} - -export type plugMiniEUWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' -} - -export type robotVacuumCleanerS1WebhookContext = deviceWebhookContext & { - workingStatus: 'Standby' | 'Clearing' | 'Paused' | 'GotoChargeBase' | 'Charging' | 'ChargeDone' | 'Dormant' | 'InTrouble' | 'InRemoteControl' | 'InDustCollecting' - onlineStatus: 'online' | 'offline' - battery: number // 0~100 -} - -export type robotVacuumCleanerS1PlusWebhookContext = deviceWebhookContext & { - workingStatus: 'Standby' | 'Clearing' | 'Paused' | 'GotoChargeBase' | 'Charging' | 'ChargeDone' | 'Dormant' | 'InTrouble' | 'InRemoteControl' | 'InDustCollecting' - onlineStatus: 'online' | 'offline' - battery: number // 0~100 -} - -export type floorCleaningRobotS10WebhookContext = deviceWebhookContext & { - workingStatus: 'Standby' | 'Clearing' | 'Paused' | 'GotoChargeBase' | 'Charging' | 'ChargeDone' | 'Dormant' | 'InTrouble' | 'InRemoteControl' | 'InDustCollecting' - onlineStatus: 'online' | 'offline' - battery: number // 0~100 - waterBaseBattery: number // 0~100 - taskType: 'standBy' | 'explore' | 'cleanAll' | 'cleanArea' | 'cleanRoom' | 'fillWater' | 'deepWashing' | 'backToCharge' | 'markingWaterBase' | 'drying' | 'collectDust' | 'remoteControl' | 'cleanWithExplorer' | 'fillWaterForHumi' | 'markingHumi' -} - -export type ceilingLightWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' - brightness: number - colorTemperature: number // 2700~6500 -} - -export type ceilingLightProWebhookContext = deviceWebhookContext & { - powerState: 'ON' | 'OFF' - brightness: number - colorTemperature: number // 2700~6500 -} - -export type keypadWebhookContext = deviceWebhookContext & { - eventName: 'createKey' | 'deleteKey' - commandId: string - result: 'success' | 'failed' | 'timeout' -} - -export type keypadTouchWebhookContext = deviceWebhookContext & { - eventName: 'createKey' | 'deleteKey' - commandId: string - result: 'success' | 'failed' | 'timeout' -} - -export type hub2WebhookContext = deviceWebhookContext & { - temperature: number - humidity: number - lightLevel: number - scale: 'CELSIUS' | 'FAHRENHEIT' -} - -export type batteryCirculatorFanWebhookContext = deviceWebhookContext & { - mode: 'direct' | 'natural' | 'sleep' | 'baby' - version: string - battery: number - powerState: 'ON' | 'OFF' - nightStatus: 'off' | 1 | 2 - oscillation: 'on' | 'off' - verticalOscillation: 'on' | 'off' - chargingStatus: 'charging' | 'uncharged' - fanSpeed: number // 1~100 -} - -export type circulatorFanWebhookContext = deviceWebhookContext & { - mode: 'direct' | 'natural' | 'sleep' | 'baby' - version: string - battery: number - powerState: 'ON' | 'OFF' - nightStatus: 'off' | 1 | 2 - oscillation: 'on' | 'off' - verticalOscillation: 'on' | 'off' - fanSpeed: number // 1~100 -} - -export type blindTiltWebhookContext = deviceWebhookContext & { - version: string - calibrate: boolean - group: boolean - direction: string - slidePosition: number // 0~100 - battery: number -} - -export type humidifierWebhookContext = deviceWebhookContext & { - temperature: number - humidity: number - scale: 'CELSIUS' | 'FAHRENHEIT' -} - -export type humidifier2WebhookContext = deviceWebhookContext & { - temperature: number - humidity: number - scale: 'CELSIUS' | 'FAHRENHEIT' -} - -export type relaySwitch1Context = deviceWebhookContext & { - online: boolean - overTemperature: boolean - switchStatus: 0 | 1 - version: string -} - -export type relaySwitch1PMContext = deviceWebhookContext & { - online: boolean - overTemperature: boolean - switchStatus: 0 | 1 - overload: boolean - version: string -} - -export type airPurifierVOCWebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export type airPurifierTableVOCWebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export type airPurifierPM25WebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export type airPurifierTablePM25WebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export type airPurifierWebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export type airPurifierTableWebhookContext = deviceWebhookContext & { - power: string - mode: number - childLock: number -} - -export interface infraredRemoteList { - device: irdevice[] -} - -export interface irdevice { - deviceId?: string - deviceName: string - remoteType: string - hubDeviceId: string -} diff --git a/src/utils/bot-ble.ts b/src/utils/bot-ble.ts new file mode 100644 index 00000000..271da8d7 --- /dev/null +++ b/src/utils/bot-ble.ts @@ -0,0 +1,136 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/bot-ble.ts: SwitchBot v4.0.0 - Bot BLE Password Helpers + */ + +import { Buffer } from 'node:buffer' + +/** + * CRC32 polynomial for password encryption + */ +const CRC32_POLYNOMIAL = 0xEDB88320 + +/** + * Precomputed CRC32 lookup table + */ +const CRC32_TABLE = new Uint32Array(256) + +// Initialize CRC32 table +for (let i = 0; i < 256; i++) { + let crc = i + for (let j = 0; j < 8; j++) { + crc = (crc & 1) !== 0 ? (crc >>> 1) ^ CRC32_POLYNOMIAL : (crc >>> 1) + } + CRC32_TABLE[i] = crc >>> 0 +} + +/** + * Calculate CRC32 checksum of a string + * @param input - String to calculate CRC32 for + * @returns CRC32 checksum as unsigned 32-bit integer + */ +function calculateCRC32(input: string): number { + let crc = 0xFFFFFFFF + for (let i = 0; i < input.length; i++) { + const byte = input.charCodeAt(i) + crc = (crc >>> 8) ^ CRC32_TABLE[(crc ^ byte) & 0xFF] + } + return (crc ^ 0xFFFFFFFF) >>> 0 +} + +/** + * Bot BLE action types + */ +export type BotBleAction = 0x00 | 0x01 | 0x02 + +/** + * Valid Bot BLE action values + */ +export const BOT_BLE_ACTIONS = { + PRESS: 0x00 as BotBleAction, + TURN_ON: 0x01 as BotBleAction, + TURN_OFF: 0x02 as BotBleAction, +} + +// Regex pattern at module scope to avoid recompilation +const PASSWORD_REGEX = /^[A-Z0-9]{4}$/i + +/** + * Validate Bot BLE password format + * Password must be exactly 4 alphanumeric characters (case-sensitive) + * @param password - Password to validate + * @throws Error if password format is invalid + */ +export function validateBotPassword(password: string): void { + if (!PASSWORD_REGEX.test(password)) { + throw new Error( + 'Invalid Bot password. Password must be exactly 4 alphanumeric characters (case-sensitive).', + ) + } +} + +/** + * Build Bot BLE command buffer + * @param action - Bot action (0x00=press, 0x01=on, 0x02=off) + * @param password - Optional 4-character password for encrypted commands + * @returns Command buffer ready to send via BLE + * @throws Error if action or password format is invalid + */ +export function buildBotBleCommand( + action: BotBleAction, + password?: string, +): Buffer { + // Validate action + const validActions = [ + BOT_BLE_ACTIONS.PRESS, + BOT_BLE_ACTIONS.TURN_ON, + BOT_BLE_ACTIONS.TURN_OFF, + ] + if (!validActions.includes(action)) { + throw new Error( + `Invalid Bot BLE action: 0x${action.toString(16)}. Expected 0x00, 0x01, or 0x02.`, + ) + } + + // Plain command (no password) + if (!password) { + return Buffer.from([0x57, 0x01, action]) + } + + // Encrypted command (with password) + validateBotPassword(password) + const crc = calculateCRC32(password) + + // Command format: [0x57, 0x11, CRC32_BE (4 bytes), action] + return Buffer.from([ + 0x57, + 0x11, + (crc >>> 24) & 0xFF, // MSB first (big-endian) + (crc >>> 16) & 0xFF, + (crc >>> 8) & 0xFF, + crc & 0xFF, // LSB + action, + ]) +} + +/** + * Parse Bot BLE response buffer + * @param response - Response buffer from Bot device + * @returns True if command was successful + * @throws Error if response indicates failure + */ +export function parseBotBleResponse(response: Buffer): boolean { + if (response.length !== 3) { + throw new Error(`Invalid Bot response length: ${response.length}, expected 3`) + } + + const statusCode = response.readUInt8(0) + + // Success codes: 0x01 (success) or 0x05 (success, encrypted) + if (statusCode === 0x01 || statusCode === 0x05) { + return true + } + + // Error response + throw new Error(`Bot command failed with status: 0x${response.toString('hex')}`) +} diff --git a/src/utils/circuit-breaker.ts b/src/utils/circuit-breaker.ts new file mode 100644 index 00000000..e10f4d18 --- /dev/null +++ b/src/utils/circuit-breaker.ts @@ -0,0 +1,243 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/circuit-breaker.ts: SwitchBot v4.0.0 - Circuit Breaker Pattern + */ + +import { Logger } from './index.js' + +/** + * Circuit breaker states + */ +export enum CircuitBreakerState { + CLOSED = 'CLOSED', // Normal operation + OPEN = 'OPEN', // Failing, reject requests + HALF_OPEN = 'HALF_OPEN', // Testing if service recovered +} + +/** + * Circuit breaker configuration + */ +export interface CircuitBreakerConfig { + /** Failure threshold (0-1) to open circuit (default: 0.5) */ + failureThreshold?: number + /** Minimum number of requests before checking threshold (default: 5) */ + minRequests?: number + /** Time to wait before attempting recovery in milliseconds (default: 30000) */ + resetTimeoutMs?: number + /** Maximum number of requests in half-open state (default: 1) */ + maxHalfOpenRequests?: number +} + +/** + * Circuit breaker statistics + */ +export interface CircuitBreakerStats { + state: CircuitBreakerState + successCount: number + failureCount: number + successRate: number + totalRequests: number + lastFailureTime?: Date + lastRecoveryTime?: Date +} + +/** + * Circuit breaker for managing connection reliability + */ +export class CircuitBreaker { + private state: CircuitBreakerState = CircuitBreakerState.CLOSED + private successCount = 0 + private failureCount = 0 + private halfOpenAttempts = 0 + private lastFailureTime?: Date + private lastRecoveryTime?: Date + private resetTimer?: NodeJS.Timeout + private logger: Logger + private config: Required + + constructor( + private name: string, + config: CircuitBreakerConfig = {}, + logLevel?: number, + ) { + this.config = { + failureThreshold: config.failureThreshold ?? 0.5, + minRequests: config.minRequests ?? 5, + resetTimeoutMs: config.resetTimeoutMs ?? 30000, + maxHalfOpenRequests: config.maxHalfOpenRequests ?? 1, + } + + this.logger = new Logger(`CircuitBreaker:${name}`, logLevel) + } + + /** + * Record a successful operation + */ + recordSuccess(): void { + this.successCount++ + + if (this.state === CircuitBreakerState.HALF_OPEN) { + // Successful in Half-Open -> recover + this.logger.info(`${this.name}: circuit recovered (HALF_OPEN -> CLOSED)`) + this.transitionToClosed() + } + } + + /** + * Record a failed operation + */ + recordFailure(): void { + this.failureCount++ + this.lastFailureTime = new Date() + + if (this.state === CircuitBreakerState.CLOSED) { + // Check if we should open the circuit + if (this.shouldOpen()) { + this.logger.warn( + `${this.name}: circuit opened - failure rate ${this.getFailureRate().toFixed(2)}`, + ) + this.transitionToOpen() + } + } else if (this.state === CircuitBreakerState.HALF_OPEN) { + // Failed during recovery -> reopen + this.logger.warn(`${this.name}: circuit reopened (HALF_OPEN -> OPEN)`) + this.transitionToOpen() + } + } + + /** + * Check if circuit should open based on failure rate + */ + private shouldOpen(): boolean { + const totalRequests = this.successCount + this.failureCount + + if (totalRequests < this.config.minRequests) { + return false + } + + const failureRate = this.failureCount / totalRequests + return failureRate >= this.config.failureThreshold + } + + /** + * Transition to CLOSED state (recovered) + */ + private transitionToClosed(): void { + this.state = CircuitBreakerState.CLOSED + this.successCount = 0 + this.failureCount = 0 + this.halfOpenAttempts = 0 + this.lastRecoveryTime = new Date() + + if (this.resetTimer) { + clearTimeout(this.resetTimer) + this.resetTimer = undefined + } + } + + /** + * Transition to OPEN state (failing) + */ + private transitionToOpen(): void { + this.state = CircuitBreakerState.OPEN + this.successCount = 0 + this.failureCount = 0 + this.halfOpenAttempts = 0 + + // Schedule recovery attempt + if (this.resetTimer) { + clearTimeout(this.resetTimer) + } + + this.resetTimer = setTimeout(() => { + this.logger.info(`${this.name}: attempting recovery (OPEN -> HALF_OPEN)`) + this.state = CircuitBreakerState.HALF_OPEN + this.halfOpenAttempts = 0 + }, this.config.resetTimeoutMs) + } + + /** + * Check if the circuit allows operations + */ + canExecute(): boolean { + if (this.state === CircuitBreakerState.CLOSED) { + return true + } + + if (this.state === CircuitBreakerState.HALF_OPEN) { + return this.halfOpenAttempts < this.config.maxHalfOpenRequests + } + + // OPEN state + return false + } + + /** + * Mark that we tried to execute in half-open state + */ + markHalfOpenAttempt(): void { + if (this.state === CircuitBreakerState.HALF_OPEN) { + this.halfOpenAttempts++ + } + } + + /** + * Get current state + */ + getState(): CircuitBreakerState { + return this.state + } + + /** + * Get current failure rate (0-1) + */ + getFailureRate(): number { + const total = this.successCount + this.failureCount + return total === 0 ? 0 : this.failureCount / total + } + + /** + * Get statistics + */ + getStats(): CircuitBreakerStats { + const totalRequests = this.successCount + this.failureCount + + return { + state: this.state, + successCount: this.successCount, + failureCount: this.failureCount, + successRate: totalRequests === 0 ? 1 : this.successCount / totalRequests, + totalRequests, + lastFailureTime: this.lastFailureTime, + lastRecoveryTime: this.lastRecoveryTime, + } + } + + /** + * Reset circuit breaker (for testing) + */ + reset(): void { + this.logger.debug(`${this.name}: reset`) + this.state = CircuitBreakerState.CLOSED + this.successCount = 0 + this.failureCount = 0 + this.halfOpenAttempts = 0 + this.lastFailureTime = undefined + this.lastRecoveryTime = undefined + + if (this.resetTimer) { + clearTimeout(this.resetTimer) + this.resetTimer = undefined + } + } + + /** + * Cleanup + */ + cleanup(): void { + if (this.resetTimer) { + clearTimeout(this.resetTimer) + this.resetTimer = undefined + } + } +} diff --git a/src/utils/connection-tracker.ts b/src/utils/connection-tracker.ts new file mode 100644 index 00000000..a7fb011d --- /dev/null +++ b/src/utils/connection-tracker.ts @@ -0,0 +1,237 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/connection-tracker.ts: SwitchBot v4.0.0 - Connection Success Tracking + */ + +import type { ConnectionType } from '../types/index.js' + +import { Logger } from './index.js' + +/** + * Statistics for a single connection type + */ +export interface ConnectionStats { + connectionType: ConnectionType + successCount: number + failureCount: number + totalAttempts: number + successRate: number + averageLatencyMs: number + lastAttemptTime?: Date + lastSuccessTime?: Date + lastFailureTime?: Date +} + +/** + * Tracks connection success/failure statistics per device per connection type + */ +export class ConnectionTracker { + private stats: Map = new Map() + private logger: Logger + + constructor( + private deviceId: string, + logLevel?: number, + ) { + this.logger = new Logger(`ConnectionTracker:${deviceId}`, logLevel) + + // Initialize stats for all connection types + const connectionTypes: ConnectionType[] = ['ble', 'api'] + for (const type of connectionTypes) { + this.stats.set(type, { + connectionType: type, + successCount: 0, + failureCount: 0, + totalAttempts: 0, + successRate: 1, // Start optimistic + averageLatencyMs: 0, + lastAttemptTime: undefined, + lastSuccessTime: undefined, + lastFailureTime: undefined, + }) + } + } + + /** + * Record a successful attempt + */ + recordSuccess(connectionType: ConnectionType, latencyMs: number = 0): void { + const stat = this.stats.get(connectionType) + if (!stat) { + return + } + + stat.successCount++ + stat.totalAttempts++ + stat.lastAttemptTime = new Date() + stat.lastSuccessTime = new Date() + + // Update average latency (exponential moving average) + const alpha = 0.3 + stat.averageLatencyMs = stat.averageLatencyMs * (1 - alpha) + latencyMs * alpha + + // Update success rate + stat.successRate = stat.totalAttempts === 0 ? 1 : stat.successCount / stat.totalAttempts + + this.logger.debug(`${connectionType}: success recorded`, { + successRate: stat.successRate.toFixed(2), + latency: latencyMs, + }) + } + + /** + * Record a failed attempt + */ + recordFailure(connectionType: ConnectionType): void { + const stat = this.stats.get(connectionType) + if (!stat) { + return + } + + stat.failureCount++ + stat.totalAttempts++ + stat.lastAttemptTime = new Date() + stat.lastFailureTime = new Date() + + // Update success rate + stat.successRate = stat.totalAttempts === 0 ? 1 : stat.successCount / stat.totalAttempts + + this.logger.debug(`${connectionType}: failure recorded`, { + successRate: stat.successRate.toFixed(2), + }) + } + + /** + * Get statistics for a connection type + */ + getStats(connectionType: ConnectionType): ConnectionStats | undefined { + return this.stats.get(connectionType) + } + + /** + * Get all statistics + */ + getAllStats(): ConnectionStats[] { + return [...this.stats.values()] + } + + /** + * Get the best connection type (highest success rate) + */ + getBestConnection(availableTypes: ConnectionType[] = ['ble', 'api']): ConnectionType | undefined { + let bestType: ConnectionType | undefined + let bestRate = -1 + + for (const type of availableTypes) { + const stat = this.stats.get(type) + if (stat && stat.successRate > bestRate) { + bestRate = stat.successRate + bestType = type + } + } + + if (bestType) { + const stat = this.stats.get(bestType)! + if (stat.totalAttempts > 0) { + this.logger.debug(`Best connection: ${bestType} (success rate: ${stat.successRate.toFixed(2)})`) + } + } + + return bestType + } + + /** + * Get the most recent successful connection type + */ + getMostRecentSuccessful(availableTypes: ConnectionType[] = ['ble', 'api']): ConnectionType | undefined { + let mostRecentType: ConnectionType | undefined + let mostRecentTime: Date | undefined + + for (const type of availableTypes) { + const stat = this.stats.get(type) + if (stat?.lastSuccessTime) { + if (!mostRecentTime || stat.lastSuccessTime > mostRecentTime) { + mostRecentTime = stat.lastSuccessTime + mostRecentType = type + } + } + } + + return mostRecentType + } + + /** + * Check if a connection type is considered reliable + * (e.g., success rate > 75% with at least 5 attempts) + */ + isReliable(connectionType: ConnectionType, minAttempts: number = 5, minRate: number = 0.75): boolean { + const stat = this.stats.get(connectionType) + if (!stat) { + return false + } + + return stat.totalAttempts >= minAttempts && stat.successRate >= minRate + } + + /** + * Get connection recommendation with reasoning + */ + getRecommendation(availableTypes: ConnectionType[] = ['ble', 'api']): { + recommended: ConnectionType | undefined + reason: string + stats: ConnectionStats[] + } { + const stats = availableTypes.map(type => this.stats.get(type)!).filter(Boolean) + + // If no attempt history, recommend first available + if (stats.every(s => s.totalAttempts === 0)) { + return { + recommended: availableTypes[0], + reason: 'No history, using first available connection', + stats, + } + } + + // Find most reliable based on success rate + const bestType = this.getBestConnection(availableTypes) + + if (!bestType) { + return { + recommended: undefined, + reason: 'No available connections', + stats, + } + } + + const bestStat = this.stats.get(bestType)! + let reason = `${bestType} has best success rate (${bestStat.successRate.toFixed(2)})` + + // Add context about latency if applicable + if (bestStat.averageLatencyMs > 0) { + reason += ` with avg latency ${bestStat.averageLatencyMs.toFixed(0)}ms` + } + + return { + recommended: bestType, + reason, + stats, + } + } + + /** + * Reset all statistics + */ + reset(): void { + this.logger.debug('Resetting all statistics') + for (const stat of this.stats.values()) { + stat.successCount = 0 + stat.failureCount = 0 + stat.totalAttempts = 0 + stat.successRate = 1 + stat.averageLatencyMs = 0 + stat.lastAttemptTime = undefined + stat.lastSuccessTime = undefined + stat.lastFailureTime = undefined + } + } +} diff --git a/src/utils/fallback-handler.ts b/src/utils/fallback-handler.ts new file mode 100644 index 00000000..78175d43 --- /dev/null +++ b/src/utils/fallback-handler.ts @@ -0,0 +1,202 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/fallback-handler.ts: SwitchBot v4.0.0 - Custom Fallback Handlers + */ + +import type { ConnectionType } from '../types/index.js' + +import { Logger } from './index.js' + +/** + * Information about a fallback event + */ +export interface FallbackEvent { + deviceId: string + primaryConnection: ConnectionType + fallbackConnection: ConnectionType | undefined + reason: string + timestamp: Date + attemptsCount?: number + totalTimeMs?: number +} + +/** + * Type for custom fallback handler callbacks + */ +export type FallbackHandler = (event: FallbackEvent) => void | Promise + +/** + * Options for registering a fallback handler + */ +export interface FallbackHandlerOptions { + /** Handler identifier for later removal */ + id?: string + /** Handler priority (higher = executes first) */ + priority?: number +} + +/** + * Manages custom fallback handlers and events + */ +export class FallbackHandlerManager { + private handlers: Map< + string, + { handler: FallbackHandler, priority: number } + > = new Map() + + private logger: Logger + private handlerCounter = 0 + + constructor(logLevel?: number) { + this.logger = new Logger('FallbackHandlerManager', logLevel) + } + + /** + * Register a custom fallback handler + */ + register( + handler: FallbackHandler, + options: FallbackHandlerOptions = {}, + ): string { + const id = options.id || `handler_${++this.handlerCounter}` + const priority = options.priority ?? 0 + + this.handlers.set(id, { handler, priority }) + this.logger.debug(`Registered fallback handler: ${id} (priority: ${priority})`) + + return id + } + + /** + * Unregister a fallback handler + */ + unregister(id: string): boolean { + const removed = this.handlers.delete(id) + if (removed) { + this.logger.debug(`Unregistered fallback handler: ${id}`) + } + return removed + } + + /** + * Emit a fallback event to all registered handlers + */ + async emit(event: FallbackEvent): Promise { + // Sort handlers by priority (descending) + + const sortedHandlers = [...this.handlers.entries()].sort((a, b) => b[1].priority - a[1].priority) + + this.logger.debug(`Emitting fallback event to ${sortedHandlers.length} handlers`, { + device: event.deviceId, + primary: event.primaryConnection, + fallback: event.fallbackConnection, + }) + + for (const [id, { handler }] of sortedHandlers) { + try { + await Promise.resolve(handler(event)) + } catch (error) { + this.logger.error(`Fallback handler ${id} threw error`, error) + // Continue with other handlers even if one fails + } + } + } + + /** + * Clear all handlers + */ + clear(): void { + this.logger.debug(`Clearing ${this.handlers.size} fallback handlers`) + this.handlers.clear() + } + + /** + * Get handler count + */ + getHandlerCount(): number { + return this.handlers.size + } +} + +/** + * Built-in fallback handler: Log fallback events + */ +export function createLoggingFallbackHandler(logLevel: number = 3): FallbackHandler { + const logger = new Logger('FallbackLogger', logLevel) + + return (event: FallbackEvent) => { + if (!event.fallbackConnection) { + logger.error( + `Device ${event.deviceId}: ${event.primaryConnection} failed and no fallback available`, + ) + } else { + logger.warn( + `Device ${event.deviceId}: ${event.primaryConnection} failed, falling back to ${event.fallbackConnection}`, + { + reason: event.reason, + attempts: event.attemptsCount, + timeMs: event.totalTimeMs, + }, + ) + } + } +} + +/** + * Built-in fallback handler: Metrics/statistics collection + */ +export function createMetricsCollectionHandler(): FallbackHandler { + const metrics: { + totalFallbacks: number + fallbacksByDevice: Map + fallbacksByConnection: Map + lastFallbackTime: Date | undefined + } = { + totalFallbacks: 0, + fallbacksByDevice: new Map(), + fallbacksByConnection: new Map(), + lastFallbackTime: undefined, + } + + const handler = (event: FallbackEvent) => { + metrics.totalFallbacks++ + metrics.lastFallbackTime = event.timestamp + + const deviceCount = metrics.fallbacksByDevice.get(event.deviceId) || 0 + metrics.fallbacksByDevice.set(event.deviceId, deviceCount + 1) + + if (event.fallbackConnection) { + const connectionKey = `${event.primaryConnection}->${event.fallbackConnection}` + const count = metrics.fallbacksByConnection.get(connectionKey) || 0 + metrics.fallbacksByConnection.set(connectionKey, count + 1) + } + } + + // Attach metrics getter to handler for retrieval + ;(handler as any).getMetrics = () => ({ ...metrics }) + + return handler +} + +/** + * Built-in fallback handler: Alert on repeated fallbacks + */ +export function createAlertHandler(alertThreshold: number = 3): FallbackHandler { + const fallbackCounts = new Map() + const logger = new Logger('FallbackAlertHandler') + + return (event: FallbackEvent) => { + const count = (fallbackCounts.get(event.deviceId) || 0) + 1 + fallbackCounts.set(event.deviceId, count) + + if (count === alertThreshold) { + logger.error( + `ALERT: Device ${event.deviceId} has fallen back ${count} times - check connection`, + ) + } + + if (count > alertThreshold && count % alertThreshold === 0) { + logger.error(`ALERT: Device ${event.deviceId} has fallen back ${count} times`) + } + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..88429b85 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,386 @@ +/** + * Recursively merges two objects, preserving old values when new values are null or undefined. + * Arrays are not deeply merged (new array replaces old). + */ +/** + * Merges two BLEAdvertisement objects recursively, preserving old values when new are null/undefined. + */ +import type { BLEAdvertisement } from '../types/ble.js' +/** + * Extracts all device-relevant options from a SwitchBotConfig object. + * Ensures future config fields are automatically supported for device instantiation. + */ +import type { ConnectionType, LogLevel, SwitchBotConfig } from '../types/index.js' + +/** + * Validates that a Buffer has at least the expected minimum length. + * Throws an error if the buffer is too short, including actual vs expected length and context. + */ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/index.ts: SwitchBot v4.0.0 - Utility Functions + */ +import { Buffer } from 'node:buffer' + +export function extractDeviceOptionsFromConfig(config: SwitchBotConfig): Record { + return { + bleConnection: config.bleConnection, + apiClient: config.apiClient, + enableFallback: config.enableFallback, + preferredConnection: config.preferredConnection as ConnectionType, + enableConnectionIntelligence: config.enableConnectionIntelligence, + enableCircuitBreaker: config.enableCircuitBreaker, + enableRetry: config.enableRetry, + retryConfig: config.retryConfig, + circuitBreakerConfig: config.circuitBreakerConfig, + logLevel: config.logLevel, + // Add more fields here as needed in the future + } +} + +export function deepMerge>(oldObj: T, newObj: Partial): T { + const result: any = Array.isArray(oldObj) ? [...oldObj] : { ...oldObj } + for (const key of Object.keys(newObj)) { + const newVal = newObj[key] + const oldVal = oldObj[key] + if (newVal === undefined || newVal === null) { + // Preserve old value + result[key] = oldVal + } else if ( + typeof oldVal === 'object' && oldVal !== null + && typeof newVal === 'object' && newVal !== null + && !Array.isArray(newVal) && !Array.isArray(oldVal) + ) { + // Recursively merge nested objects + result[key] = deepMerge(oldVal, newVal) + } else { + // Use new value + result[key] = newVal + } + } + return result +} +export function mergeAdvertisement(oldAdv: T, newAdv: Partial): T { + return deepMerge(oldAdv, newAdv) +} + +export function validateResponseLength(buffer: Buffer, minLength: number, context: string): void { + if (!buffer || buffer.length < minLength) { + throw new Error( + `Truncated response in ${context}: expected at least ${minLength} bytes, got ${buffer ? buffer.length : 0}`, + ) + } +} + +/** + * Logger utility for consistent logging across the library + */ +export class Logger { + constructor( + private readonly name: string, + private level: LogLevel = 2, // WARN by default + ) { } + + setLevel(level: LogLevel): void { + this.level = level + } + + error(message: string, ...args: any[]): void { + if (this.level >= 1) { + console.error(`[${this.name}] ERROR:`, message, ...args) + } + } + + warn(message: string, ...args: any[]): void { + if (this.level >= 2) { + console.warn(`[${this.name}] WARN:`, message, ...args) + } + } + + info(message: string, ...args: any[]): void { + if (this.level >= 3) { + console.warn(`[${this.name}] INFO:`, message, ...args) + } + } + + debug(message: string, ...args: any[]): void { + if (this.level >= 4) { + console.warn(`[${this.name}] DEBUG:`, message, ...args) + } + } +} + +// Regex patterns at module scope to avoid recompilation +const MAC_REGEX = /^(?:[0-9A-F]{2}[:-]){5}[0-9A-F]{2}$/i +const DASH_REGEX = /-/g +const COLON_REGEX = /:/g + +/** + * Validate MAC address format + */ +export function isValidMAC(mac: string): boolean { + return MAC_REGEX.test(mac) +} + +/** + * Normalize MAC address to lowercase with colons + */ +export function normalizeMAC(mac: string): string { + return mac.toLowerCase().replace(DASH_REGEX, ':') +} + +/** + * Convert MAC address to device ID format + */ +export function macToDeviceId(mac: string): string { + return mac.replace(COLON_REGEX, '').toUpperCase() +} + +/** + * Extract MAC address from manufacturer data (SwitchBot: company ID 0x0969) + * Bytes: [2 bytes company ID (69 09)] + [6 bytes MAC] + ... + */ +export function extractMacFromManufacturerData(manufacturerDataHex?: unknown): string | undefined { + if (!manufacturerDataHex || typeof manufacturerDataHex !== 'string') { + return undefined + } + + // Check if hex string starts with 6909 (SwitchBot company ID in little-endian) + if (!manufacturerDataHex.startsWith('6909')) { + return undefined + } + + // Extract 6 bytes (12 hex chars) starting at position 4 (after company ID) + const macHex = manufacturerDataHex.substring(4, 16) + if (macHex.length !== 12) { + return undefined + } + + // Convert to MAC address format: XX:XX:XX:XX:XX:XX + return [ + macHex.substring(0, 2), + macHex.substring(2, 4), + macHex.substring(4, 6), + macHex.substring(6, 8), + macHex.substring(8, 10), + macHex.substring(10, 12), + ].join(':').toUpperCase() +} + +/** + * Delay utility + */ +export function delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)) +} + +/** + * Timeout promise wrapper + */ +export async function withTimeout( + promise: Promise, + timeoutMs: number, + errorMessage = 'Operation timed out', +): Promise { + let timeoutHandle: NodeJS.Timeout + + const timeoutPromise = new Promise((_, reject) => { + timeoutHandle = setTimeout(() => reject(new Error(errorMessage)), timeoutMs) + }) + + try { + const result = await Promise.race([promise, timeoutPromise]) + clearTimeout(timeoutHandle!) + return result + } catch (error) { + clearTimeout(timeoutHandle!) + throw error + } +} + +/** + * Retry utility with exponential backoff + */ +export async function retry( + fn: () => Promise, + options: { + maxAttempts?: number + delayMs?: number + backoff?: boolean + onRetry?: (attempt: number, error: Error) => void + } = {}, +): Promise { + const { + maxAttempts = 3, + delayMs = 1000, + backoff = true, + onRetry, + } = options + + let lastError: Error | undefined + + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + try { + return await fn() + } catch (error) { + lastError = error as Error + + if (attempt < maxAttempts) { + const waitTime = backoff ? delayMs * attempt : delayMs + onRetry?.(attempt, lastError) + await delay(waitTime) + } + } + } + + throw lastError ?? new Error('Retry failed without a captured error') +} + +/** + * Clamp a number between min and max + */ +export function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max) +} + +/** + * Convert temperature from Celsius to Fahrenheit + */ +export function celsiusToFahrenheit(celsius: number): number { + return (celsius * 9 / 5) + 32 +} + +/** + * Convert temperature from Fahrenheit to Celsius + */ +export function fahrenheitToCelsius(fahrenheit: number): number { + return (fahrenheit - 32) * 5 / 9 +} + +/** + * Parse hex string to buffer + */ +export function hexToBuffer(hex: string): Buffer { + return Buffer.from(hex, 'hex') +} + +/** + * Convert buffer to hex string + */ +export function bufferToHex(buffer: Buffer): string { + return buffer.toString('hex') +} + +/** + * Generate random nonce for API requests + */ +export function generateNonce(): string { + return Math.random().toString(36).substring(2, 15) + + Math.random().toString(36).substring(2, 15) +} + +/** + * Generate timestamp for API requests + */ +export function generateTimestamp(): string { + return Date.now().toString() +} + +/** + * Create HMAC-SHA256 signature for OpenAPI + */ +export async function createSignature( + token: string, + secret: string, + timestamp: string, + nonce: string, +): Promise { + const crypto = await import('node:crypto') + const data = `${token}${timestamp}${nonce}` + return crypto.createHmac('sha256', secret).update(data).digest('base64') +} + +/** + * Safe JSON parse with fallback + */ +export function safeJsonParse(json: string, fallback: T): T { + try { + return JSON.parse(json) + } catch { + return fallback + } +} + +/** + * Check if value is a promise + */ +export function isPromise(value: any): value is Promise { + return value && typeof value.then === 'function' +} + +/** + * Deep clone an object + */ +export function deepClone(obj: T): T { + return JSON.parse(JSON.stringify(obj)) +} + +/** + * Debounce function + */ +export function debounce any>( + fn: T, + delayMs: number, +): (...args: Parameters) => void { + let timeoutId: NodeJS.Timeout | null = null + + return (...args: Parameters) => { + if (timeoutId) { + clearTimeout(timeoutId) + } + timeoutId = setTimeout(() => { + fn(...args) + timeoutId = null + }, delayMs) + } +} + +/** + * Throttle function + */ +export function throttle any>( + fn: T, + limitMs: number, +): (...args: Parameters) => void { + let lastRun = 0 + + return (...args: Parameters) => { + const now = Date.now() + if (now - lastRun >= limitMs) { + fn(...args) + lastRun = now + } + } +} + +// Export Bot BLE password utilities +export { + BOT_BLE_ACTIONS, + type BotBleAction, + buildBotBleCommand, + parseBotBleResponse, + validateBotPassword, +} from './bot-ble.js' +export { CircuitBreaker, type CircuitBreakerConfig, CircuitBreakerState, type CircuitBreakerStats } from './circuit-breaker.js' +export { type ConnectionStats, ConnectionTracker } from './connection-tracker.js' +export { + createAlertHandler, + createLoggingFallbackHandler, + createMetricsCollectionHandler, + type FallbackEvent, + type FallbackHandler, + FallbackHandlerManager, + type FallbackHandlerOptions, +} from './fallback-handler.js' +// Export advanced utilities +export { type RetryConfig, RetryExecutor, type RetryResult } from './retry.js' diff --git a/src/utils/relay-encryption.ts b/src/utils/relay-encryption.ts new file mode 100644 index 00000000..87a8f443 --- /dev/null +++ b/src/utils/relay-encryption.ts @@ -0,0 +1,27 @@ +import { Buffer } from 'node:buffer' +import crypto from 'node:crypto' + +/** + * Encrypts a relay switch BLE command using AES-128-CTR if key is provided. + * @param cmd - Command as Buffer or number[] + * @param keyHex - 16-byte hex string + * @param ivHex - 16-byte hex string (optional, defaults to 0) + * @returns Encrypted command as Buffer + */ +export function encryptRelayCommandIfNeeded( + cmd: Buffer | number[], + keyHex: string, + ivHex?: string, +): Buffer { + const key = Buffer.from(keyHex, 'hex') + if (key.length !== 16) { + throw new Error('Relay encryptionKey must be 16 bytes (32 hex chars)') + } + const iv = ivHex ? Buffer.from(ivHex, 'hex') : Buffer.alloc(16, 0) + const input = Buffer.isBuffer(cmd) ? cmd : Buffer.from(cmd) + // For now, always use CTR mode (SwitchBot default for relay/lock) + const cipher = crypto.createCipheriv('aes-128-ctr', key, iv) + const encrypted = Buffer.concat([cipher.update(input), cipher.final()]) + // Prepend 0x11 to indicate encrypted command (SwitchBot convention) + return Buffer.concat([Buffer.from([0x11]), encrypted]) +} diff --git a/src/utils/retry.ts b/src/utils/retry.ts new file mode 100644 index 00000000..9c1286d8 --- /dev/null +++ b/src/utils/retry.ts @@ -0,0 +1,210 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * utils/retry.ts: SwitchBot v4.0.0 - Retry Logic with Exponential Backoff + */ + +import { Logger } from './index.js' + +// BLEAK_RETRY_EXCEPTIONS: error messages/types that should trigger a retry +const BLEAK_RETRY_EXCEPTIONS = [ + 'Device with address', + 'Failed to connect to peripheral', + 'org.freedesktop.DBus.Error', + 'org.bluez.Error', + 'Connection was reset', + 'Connection timed out', + 'Operation already in progress', + 'Operation failed', + 'Not connected', + 'No such device', + 'Resource temporarily unavailable', + 'Software caused connection abort', + 'Connection refused', + 'Connection reset by peer', + 'Connection aborted', + 'Connection error', + 'TimeoutError', +] + +/** + * Retry configuration options + */ +export interface RetryConfig { + /** Maximum number of retry attempts (default: 3) */ + maxAttempts?: number + /** Initial delay in milliseconds (default: 100) */ + initialDelayMs?: number + /** Maximum delay in milliseconds (default: 5000) */ + maxDelayMs?: number + /** Exponential backoff multiplier (default: 2) */ + backoffMultiplier?: number + /** Jitter factor 0-1 to randomize delays (default: 0.1) */ + jitterFactor?: number +} + +/** + * Retry execution result + */ +export interface RetryResult { + /** Whether the operation succeeded */ + success: boolean + /** The result (if successful) */ + result?: T + /** The error (if failed) */ + error?: Error + /** Number of attempts made */ + attemptsCount: number + /** Total time spent retrying in milliseconds */ + totalTimeMs: number +} + +/** + * DBus/BlueZ error regex (moved to module scope for performance) + */ +const DBUS_ERROR_REGEX = /org\.freedesktop\.DBus|org\.bluez|DBus|BlueZ/i + +/** + * Retry executor with exponential backoff + */ +export class RetryExecutor { + private logger: Logger + private config: Required + + constructor(config: RetryConfig = {}, logLevel?: number) { + this.config = { + maxAttempts: config.maxAttempts ?? 3, + initialDelayMs: config.initialDelayMs ?? 100, + maxDelayMs: config.maxDelayMs ?? 5000, + backoffMultiplier: config.backoffMultiplier ?? 2, + jitterFactor: config.jitterFactor ?? 0.1, + } + + this.logger = new Logger('RetryExecutor', logLevel) + } + + /** + * Calculate delay for next attempt with exponential backoff + */ + private calculateDelay(attemptNumber: number): number { + const exponentialDelay + = this.config.initialDelayMs * this.config.backoffMultiplier ** (attemptNumber - 1) + const cappedDelay = Math.min(exponentialDelay, this.config.maxDelayMs) + + // Add jitter to prevent thundering herd + const jitter = cappedDelay * this.config.jitterFactor * (Math.random() * 2 - 1) + return Math.max(0, cappedDelay + jitter) + } + + /** + * Execute a function with automatic retries and exponential backoff + */ + + async execute( + fn: () => Promise, + description = 'Operation', + ): Promise> { + let lastError: Error | undefined + let totalTimeMs = 0 + let attemptNumber = 0 + + for (attemptNumber = 1; attemptNumber <= this.config.maxAttempts; attemptNumber++) { + try { + const startTime = Date.now() + const result = await fn() + const elapsedMs = Date.now() - startTime + totalTimeMs += elapsedMs + + if (attemptNumber > 1) { + this.logger.info( + `${description} succeeded on attempt ${attemptNumber}/${this.config.maxAttempts}`, + ) + } + + return { + success: true, + result, + attemptsCount: attemptNumber, + totalTimeMs, + } + } catch (error) { + lastError = error instanceof Error ? error : new Error(String(error)) + const errorMsg = lastError.message || String(lastError) + const isDBusError = DBUS_ERROR_REGEX.test(errorMsg) + const isBleakRetry = BLEAK_RETRY_EXCEPTIONS.some(msg => errorMsg.includes(msg)) + const elapsedMs = Date.now() - (Date.now() - totalTimeMs) + totalTimeMs += elapsedMs + + if (attemptNumber < this.config.maxAttempts && (isDBusError || isBleakRetry || attemptNumber < this.config.maxAttempts)) { + // DBus error: always backoff 0.25s (250ms) before normal backoff + if (isDBusError) { + this.logger.warn( + `${description} DBus error detected on attempt ${attemptNumber}, applying 250ms backoff`, + { error: errorMsg }, + ) + await new Promise(resolve => setTimeout(resolve, 250)) + } + const delayMs = this.calculateDelay(attemptNumber) + this.logger.warn( + `${description} failed on attempt ${attemptNumber}/${this.config.maxAttempts}, retrying in ${delayMs}ms`, + { + error: errorMsg, + attempt: attemptNumber, + errorType: lastError.name, + isDBusError, + isBleakRetry, + }, + ) + await new Promise(resolve => setTimeout(resolve, delayMs)) + } else { + this.logger.error( + `${description} failed after ${attemptNumber} attempts`, + { + error: errorMsg, + attempt: attemptNumber, + errorType: lastError.name, + isDBusError, + isBleakRetry, + }, + ) + } + } + } + + return { + success: false, + error: new Error( + `Retry failed after ${attemptNumber - 1} attempts. Last error: ${lastError?.name || 'Unknown'}: ${lastError?.message || 'Unknown error'}`, + ), + attemptsCount: attemptNumber - 1, + totalTimeMs, + } + } + + /** + * Convenience method: execute with retries, throw on final failure + */ + async executeOrThrow( + fn: () => Promise, + description = 'Operation', + ): Promise { + const result = await this.execute(fn, description) + + if (result.success) { + return result.result! + } + + throw result.error + } +} + +/** + * Convenience function: retry a promise with automatic backoff + */ +export async function retry( + fn: () => Promise, + config: RetryConfig = {}, + logLevel?: number, +): Promise { + const executor = new RetryExecutor(config, logLevel) + return executor.executeOrThrow(fn) +} diff --git a/test/README.md b/test/README.md new file mode 100644 index 00000000..07372504 --- /dev/null +++ b/test/README.md @@ -0,0 +1,18 @@ +# Test Suite Structure + +This directory contains all automated tests for the project, organized by domain for clarity and maintainability. + +- **devices/**: Tests for individual device classes and features +- **apis/**: Tests for API integrations and endpoints +- **types/**: Type/interface validation and type-level tests +- **utils/**: Shared test utilities, mocks, and their own tests +- **integration/**: End-to-end or scenario-based integration tests + +## Conventions +- Place each device or feature test in its respective folder. +- Use the utils/ folder for reusable mocks, fixtures, and helpers. +- Add new folders as the project grows, following this pattern. + +--- + +Feel free to update this file as the test suite evolves. \ No newline at end of file diff --git a/test/apis/ble-connection-cleanup.test.ts b/test/apis/ble-connection-cleanup.test.ts new file mode 100644 index 00000000..2108d6b9 --- /dev/null +++ b/test/apis/ble-connection-cleanup.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'vitest' + +import { BLEConnection } from '../../src/ble.js' + +function createPeripheralMissingCharacteristics() { + const peripheral = { + id: 'mock-id-1', + address: 'AA:BB:CC:DD:EE:FF', + connect: (callback: (error?: Error) => void) => callback(), + disconnectCalls: 0, + disconnect: (callback: () => void) => { + peripheral.disconnectCalls += 1 + callback() + }, + discoverSomeServicesAndCharacteristics: ( + _services: string[], + _characteristics: string[], + callback: (error: Error | null, services: any[], chars: any[]) => void, + ) => { + callback(null, [], []) + }, + } + + return peripheral +} + +describe('bLEConnection cleanup on characteristic discovery failure', () => { + it('cleans connection maps and disconnects peripheral when required chars are missing', async () => { + const peripheral = createPeripheralMissingCharacteristics() + const noble = { + peripherals: [peripheral], + } + + const connection = new BLEConnection({ noble }) + + await expect(connection.connect('AA:BB:CC:DD:EE:FF')).rejects.toThrow('Required characteristics not found') + + const connectionInternal = connection as any + expect(connectionInternal.connections.size).toBe(0) + expect(connectionInternal.characteristics.size).toBe(0) + expect(peripheral.disconnectCalls).toBe(1) + }) +}) diff --git a/test/apis/ble-notification-handling.test.ts b/test/apis/ble-notification-handling.test.ts new file mode 100644 index 00000000..62763df4 --- /dev/null +++ b/test/apis/ble-notification-handling.test.ts @@ -0,0 +1,92 @@ +import { Buffer } from 'node:buffer' +import { EventEmitter } from 'node:events' + +import { describe, expect, it, vi } from 'vitest' + +import { BLEConnection } from '../../src/ble.js' +import { Logger } from '../../src/utils/index.js' + +describe('bLEConnection notification handling', () => { + function createPeripheralWithNotify() { + // Provide both dashed and undashed UUIDs for compatibility + const writeChar = { + uuid: 'cba20002224d11e69fb80002a5d5c51b', + write: vi.fn((data: Buffer, withoutResponse: boolean, cb: (err?: Error) => void) => cb()), + on: vi.fn(), + subscribe: vi.fn(), + } + const notifyChar = new EventEmitter() as any + notifyChar.uuid = 'cba20003224d11e69fb80002a5d5c51b' + notifyChar.subscribe = (cb: (e?: Error) => void) => cb() + return { + id: 'mock-id', + address: 'AA:BB:CC:DD:EE:FF', + connect: (cb: (err?: Error) => void) => cb(), + disconnect: (cb: () => void) => cb(), + discoverSomeServicesAndCharacteristics: (_s: string[], _c: string[], cb: (e: null, s: any[], c: any[]) => void) => { + cb(null, [], [writeChar, notifyChar]) + }, + notifyChar, + } + } + + it('resolves per-command notification future and times out if not received', async () => { + const peripheral = createPeripheralWithNotify() + const noble = { peripherals: [peripheral] } + const connection = new BLEConnection({ noble }) + await connection.connect('AA:BB:CC:DD:EE:FF') + // Subscribe to notifications to set up handler and log when called + await connection.subscribeNotifications('AA:BB:CC:DD:EE:FF', (payload) => { + // eslint-disable-next-line no-console + console.log('Custom handler called with:', payload) + }) + + // Send command expecting notification + const sendPromise = connection.sendCommand('AA:BB:CC:DD:EE:FF', Buffer.from([0x01]), { expectNotification: true, notificationTimeoutMs: 200 }) + // Poll until the notification future is set, then emit the notification + const normalizedMac = 'aa:bb:cc:dd:ee:ff' + let notified = false + while (!(connection as any).notificationFutures.has(normalizedMac)) { + await new Promise(r => setTimeout(r, 1)) + } + if (!notified) { + notified = true + peripheral.notifyChar.emit('data', Buffer.from([0xA5])) + } + const result = await sendPromise + expect(result!.equals(Buffer.from([0xA5]))).toBe(true) + + // Test timeout + await expect(connection.sendCommand('AA:BB:CC:DD:EE:FF', Buffer.from([0x02]), { expectNotification: true, notificationTimeoutMs: 30 })).rejects.toThrow('Notification timeout') + }) + + it('logs unsolicited notifications', async () => { + const peripheral = createPeripheralWithNotify() + const noble = { peripherals: [peripheral] } + class TestLogger extends Logger { + constructor() { + super('MockLogger', 4) + } + + setLevel = vi.fn() + info = vi.fn() + debug = vi.fn() + warn = vi.fn() + error = vi.fn() + } + const mockLogger = new TestLogger() + const infoSpy = mockLogger.info + const connection = new BLEConnection({ noble, logLevel: 0, logger: mockLogger }) + await connection.connect('AA:BB:CC:DD:EE:FF') + // Emit unsolicited notification + // Debug: log when emitting + // eslint-disable-next-line no-console + console.log('Emitting unsolicited notification') + peripheral.notifyChar.emit('data', Buffer.from([0x99])) + // Directly call logger to confirm spy works + mockLogger.info('Unsolicited notification from test: 99', 'test') + // Wait for event loop to process notification + await new Promise(r => setTimeout(r, 200)) + expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('Unsolicited notification'), expect.any(String)) + }) +}) diff --git a/test/apis/ble-scanner-lifecycle.test.ts b/test/apis/ble-scanner-lifecycle.test.ts new file mode 100644 index 00000000..ad1c639a --- /dev/null +++ b/test/apis/ble-scanner-lifecycle.test.ts @@ -0,0 +1,75 @@ +import { Buffer } from 'node:buffer' +import { EventEmitter } from 'node:events' + +import { describe, expect, it } from 'vitest' + +import { BLEScanner } from '../../src/ble.js' + +class MockNoble extends EventEmitter { + state = 'poweredOn' + + startScanning(): void { + this.emit('scanStart') + } + + stopScanning(): void { + this.emit('scanStop') + } +} + +function createPeripheral(overrides: Record = {}): any { + return { + id: 'mock-device-id', + address: 'AA:BB:CC:DD:EE:FF', + rssi: -45, + connectable: true, + advertisement: { + serviceData: [ + { + uuid: 'fd3d', + data: Buffer.from([0x48, 0x00, 0x50]), + }, + ], + }, + ...overrides, + } +} + +describe('bLEScanner lifecycle', () => { + it('deduplicates noble listeners and removes them on destroy', () => { + const noble = new MockNoble() + const scanner = new BLEScanner({ noble }) + + expect(noble.listenerCount('stateChange')).toBe(1) + expect(noble.listenerCount('discover')).toBe(1) + expect(noble.listenerCount('scanStart')).toBe(1) + expect(noble.listenerCount('scanStop')).toBe(1) + + ;(scanner as any).setupNobleHandlers() + + expect(noble.listenerCount('stateChange')).toBe(1) + expect(noble.listenerCount('discover')).toBe(1) + expect(noble.listenerCount('scanStart')).toBe(1) + expect(noble.listenerCount('scanStop')).toBe(1) + + scanner.destroy() + + expect(noble.listenerCount('stateChange')).toBe(0) + expect(noble.listenerCount('discover')).toBe(0) + expect(noble.listenerCount('scanStart')).toBe(0) + expect(noble.listenerCount('scanStop')).toBe(0) + }) + + it('keeps discovered devices after stopScan', () => { + const noble = new MockNoble() + const scanner = new BLEScanner({ noble }) + + noble.emit('discover', createPeripheral()) + expect(scanner.getDiscoveredDevices()).toHaveLength(1) + + scanner.stopScan() + expect(scanner.getDiscoveredDevices()).toHaveLength(1) + + scanner.destroy() + }) +}) diff --git a/test/apis/discovery.test.ts b/test/apis/discovery.test.ts new file mode 100644 index 00000000..4f908e26 --- /dev/null +++ b/test/apis/discovery.test.ts @@ -0,0 +1,152 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +describe('discovery fallback behavior', () => { + it('uses advertisement.id when BLE address is an empty string', async () => { + const switchbot = new SwitchBot({ + enableBLE: false, + token: '', + secret: '', + }) + + await (switchbot as any).handleBLEDiscovery({ + id: 'macos-empty-address-id', + address: '', + isAddressable: false, + rssi: -45, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 88, + }, + }) + + const devices = switchbot.devices.list() + expect(devices).toHaveLength(1) + expect(devices[0]?.getId()).toBe('macos-empty-address-id') + expect(devices[0]?.getMAC()).toBeUndefined() + }) + + it('uses advertisement.id when BLE address is missing', async () => { + const switchbot = new SwitchBot({ + enableBLE: false, + token: '', + secret: '', + }) + + await (switchbot as any).handleBLEDiscovery({ + id: 'macos-missing-address-id', + isAddressable: false, + rssi: -50, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 75, + }, + }) + + const devices = switchbot.devices.list() + expect(devices).toHaveLength(1) + expect(devices[0]?.getId()).toBe('macos-missing-address-id') + expect(devices[0]?.getMAC()).toBeUndefined() + }) + + it('extracts MAC from manufacturer data when address is empty', async () => { + const switchbot = new SwitchBot({ + enableBLE: false, + token: '', + secret: '', + }) + + // Simulate handleBLEDiscovery receiving already-extracted MAC from manufacturer data + // In real usage, BLE scanner.handleDiscovery extracts the MAC from manufacturer data + await (switchbot as any).handleBLEDiscovery({ + id: 'peripheral-uuid-1', + address: 'CA:8F:1D:76:12:E1', // This would be extracted from manufacturer data by BLE scanner + isAddressable: true, + rssi: -55, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 90, + }, + }) + + const devices = switchbot.devices.list() + expect(devices).toHaveLength(1) + // MAC should be available (extracted from manufacturer data by BLE scanner) + expect(devices[0]?.getMAC()).toBe('CA:8F:1D:76:12:E1') + }) + + it('supports legacy service UUID (000d)', async () => { + const switchbot = new SwitchBot({ + enableBLE: false, + token: '', + secret: '', + }) + + ;(switchbot as any).scanner = { + on: () => {}, + off: () => {}, + start: async () => {}, + stop: async () => {}, + getDiscoveredDevices: () => [], + getDevice: () => undefined, + waitForDevice: async () => ({ + id: 'legacy-uuid-device', + address: 'AA:BB:CC:DD:EE:FF', + isAddressable: true, + rssi: -60, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 85, + }, + }), + } + + await (switchbot as any).handleBLEDiscovery({ + id: 'legacy-uuid-device', + address: 'AA:BB:CC:DD:EE:FF', + isAddressable: true, + rssi: -60, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 85, + }, + }) + + const devices = switchbot.devices.list() + expect(devices).toHaveLength(1) + expect(devices[0]?.getId()).toBe('AABBCCDDEEFF') + expect(devices[0]?.getMAC()).toBe('AA:BB:CC:DD:EE:FF') + }) + + it('stores and retrieves devices by BLE ID when MAC is unavailable', async () => { + const switchbot = new SwitchBot({ + enableBLE: false, + token: '', + secret: '', + }) + + await (switchbot as any).handleBLEDiscovery({ + id: 'device-ble-uuid-001', + bleId: 'device-ble-uuid-001', + address: undefined, + isAddressable: false, + rssi: -70, + serviceData: { + model: 'H', + modelName: 'Bot', + battery: 75, + }, + }) + + const devices = switchbot.devices.list() + expect(devices).toHaveLength(1) + expect(devices[0]?.getId()).toBe('device-ble-uuid-001') + expect(devices[0]?.getInfo().bleId).toBe('device-ble-uuid-001') + }) +}) diff --git a/test/apis/openapi-get-devices.test.ts b/test/apis/openapi-get-devices.test.ts new file mode 100644 index 00000000..06222c8b --- /dev/null +++ b/test/apis/openapi-get-devices.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it, vi } from 'vitest' + +import { OpenAPIClient } from '../../src/api.js' + +describe('openAPIClient.getDevices', () => { + it('fetches device list from API', async () => { + const mockDevices = { + deviceList: [ + { deviceId: 'abc', deviceName: 'Test Device', deviceType: 'WoHand', enableCloudService: true, hubDeviceId: 'hub1', version: '1.0.0' }, + ], + } + const client = new OpenAPIClient('token', 'secret') + vi.spyOn(client as any, 'makeRequest').mockResolvedValue({ statusCode: 100, message: 'ok', body: mockDevices }) + const result = await client.getDevices() + expect(result).toEqual(mockDevices) + }) +}) diff --git a/test/apis/switchbot-discover-api.test.ts b/test/apis/switchbot-discover-api.test.ts new file mode 100644 index 00000000..97b5e40d --- /dev/null +++ b/test/apis/switchbot-discover-api.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, it, vi } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +describe('switchBot.discover (API only)', () => { + it('discovers devices from cloud API', async () => { + const mockDevices = { + deviceList: [ + { deviceId: 'abc', deviceName: 'Test Device', deviceType: 'Bot', enableCloudService: true, hubDeviceId: 'hub1', version: '1.0.0' }, + ], + } + const bot = new SwitchBot({ token: 'token', secret: 'secret', logLevel: 4 }) // DEBUG + bot.setLogLevel(4) + // Wait for API client to be initialized + await new Promise(resolve => setTimeout(resolve, 10)) + const apiClient = bot.getAPIClient() + if (!apiClient) { + throw new Error('API client not initialized') + } + vi.spyOn(apiClient, 'getDevices').mockResolvedValue(mockDevices) + // Patch: Ensure deviceType is mapped and device creation is awaited + const devices = await bot.discover({ scanBLE: false, fetchAPI: true }) + // Wait for async device creation + await new Promise(resolve => setTimeout(resolve, 50)) + expect(devices.length).toBeGreaterThanOrEqual(1) + const device = devices[0] + expect(device.getId()).toBe('abc') + expect(device.getName()).toBe('Test Device') + expect(device.getInfo().connectionTypes).toContain('api') + }) +}) diff --git a/test/devices/airpurifier-encryption.test.ts b/test/devices/airpurifier-encryption.test.ts new file mode 100644 index 00000000..f20b42fb --- /dev/null +++ b/test/devices/airpurifier-encryption.test.ts @@ -0,0 +1,49 @@ +import { Buffer } from 'node:buffer' + +import { describe, expect, it, vi } from 'vitest' + +import { WoAirPurifier } from '../../src/devices/wo-air-purifier.js' +import { DEVICE_COMMANDS } from '../../src/settings.js' + +const ENCRYPTION_KEY = '00112233445566778899aabbccddeeff' // 16 bytes hex +const ENCRYPTION_IV = '0102030405060708090a0b0c0d0e0f10' // 16 bytes hex + +describe('air Purifier BLE encryption', () => { + it('sends encrypted command when encryptionKey is present', async () => { + const air = new WoAirPurifier({ + id: 'test-air', + name: 'Test Air', + deviceType: 'Air Purifier', + connectionTypes: ['ble'], + encryptionKey: ENCRYPTION_KEY, + encryptionIV: ENCRYPTION_IV, + }) + const sent: Buffer[] = [] + ;(air as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await air.turnOn() + expect(sent.length).toBe(1) + expect(sent[0][0]).toBe(0x11) + expect(sent[0].equals(Buffer.from(DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON))).toBe(false) + }) + + it('sends plain command when encryptionKey is absent', async () => { + const air = new WoAirPurifier({ + id: 'test-air', + name: 'Test Air', + deviceType: 'Air Purifier', + connectionTypes: ['ble'], + }) + const sent: Buffer[] = [] + ;(air as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await air.turnOn() + expect(sent.length).toBe(1) + expect(sent[0][0]).not.toBe(0x11) + expect(sent[0].equals(Buffer.from(DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON))).toBe(true) + }) +}) diff --git a/test/devices/airpurifier-preset-mode.test.ts b/test/devices/airpurifier-preset-mode.test.ts new file mode 100644 index 00000000..40afcb66 --- /dev/null +++ b/test/devices/airpurifier-preset-mode.test.ts @@ -0,0 +1,38 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoAirPurifier } from '../../src/devices/wo-air-purifier.js' + +function airPurifierInfo(): DeviceInfo { + return { + id: 'air-01', + name: 'Air Purifier', + deviceType: 'Air Purifier', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('air purifier preset modes', () => { + it('setPresetMode sends correct BLE command for each mode', async () => { + const purifier = new WoAirPurifier(airPurifierInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(purifier as any).sendCommand = sendCommand + + const modes = ['level_1', 'level_2', 'level_3', 'auto', 'sleep', 'pet'] as const + for (const mode of modes) { + await purifier.setPresetMode(mode) + expect(sendCommand).toHaveBeenLastCalledWith( + expect.arrayContaining([0x57, 0x02, expect.any(Number)]), + 'setPresetMode', + mode, + ) + } + }) + + it('throws for unsupported mode', async () => { + const purifier = new WoAirPurifier(airPurifierInfo()) + await expect(purifier.setPresetMode('invalid' as any)).rejects.toThrow('Unsupported preset mode') + }) +}) diff --git a/test/devices/airpurifier-status.test.ts b/test/devices/airpurifier-status.test.ts new file mode 100644 index 00000000..cbab0471 --- /dev/null +++ b/test/devices/airpurifier-status.test.ts @@ -0,0 +1,88 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { OpenAPIClient } from '../../src/api.js' +import { WoAirPurifier } from '../../src/devices/wo-air-purifier.js' + +function airPurifierInfo(): DeviceInfo { + return { + id: 'air-01', + name: 'Air Purifier', + deviceType: 'Air Purifier', + connectionTypes: ['ble', 'api'], + mac: 'AA:BB:CC:DD:EE:FF', + cloudServiceEnabled: true, + } +} + +// Helper subclass to inject a mock API client + +// Helper subclass to inject a mock API client with all required properties +class TestWoAirPurifier extends WoAirPurifier { + constructor(info: DeviceInfo, apiClient: any) { + super(info, { apiClient }) + // Patch: Ensure apiClient is set on the instance for hasAPI() + this.apiClient = apiClient + // Force hasAPI to always return true + this.hasAPI = () => true + this.hasBLE = () => false + } + + // Add public setters for protected properties for testing + setPreferredConnection(val: any) { this.preferredConnection = val } + setEnableFallback(val: any) { this.enableFallback = val } +} + +describe('air purifier status', () => { + it('returns full status from API', async () => { + // Use a real OpenAPIClient instance with a mocked getStatus + const realApiClient = new OpenAPIClient('test-token', 'test-secret') + vi.spyOn(realApiClient, 'getStatus').mockResolvedValue({ + power: 'on', + fanSpeed: 3, + airMode: 'auto', + pm25: 42, + version: '1.0', + deviceId: '', + deviceType: '', + hubDeviceId: '', + }) + const purifier = new TestWoAirPurifier({ + ...airPurifierInfo(), + connectionTypes: ['api'], + cloudServiceEnabled: true, + id: 'air-01', + name: 'Air Purifier', + deviceType: 'Air Purifier', + }, realApiClient) + purifier.setPreferredConnection('api') + purifier.setEnableFallback(false) + const status = await purifier.getStatus() + expect(status.power).toBe('on') + expect(status.fanSpeed).toBe(3) + expect(status.mode).toBe('auto') + expect(status.pm25).toBe(42) + expect(status.airQuality).toBe('good') + expect(status.version).toBe('1.0') + }) + + it('returns full status from BLE', async () => { + const purifier = new WoAirPurifier(airPurifierInfo()) + ;(purifier as any).hasAPI = () => false + ;(purifier as any).hasBLE = () => true + ;(purifier as any).getBLEStatus = vi.fn().mockResolvedValue({ + state: true, + fanSpeed: 2, + mode: 'manual', + pm25: 120, + }) + const status = await purifier.getStatus() + expect(status.power).toBe('on') + expect(status.fanSpeed).toBe(2) + expect(status.mode).toBe('manual') + expect(status.pm25).toBe(120) + // BLE fallback does not compute airQuality + expect(status.airQuality).toBeUndefined() + }) +}) diff --git a/test/devices/art-frame.test.ts b/test/devices/art-frame.test.ts new file mode 100644 index 00000000..8745aac2 --- /dev/null +++ b/test/devices/art-frame.test.ts @@ -0,0 +1,56 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * art-frame.test.ts: SwitchBot v4.0.0 - Art Frame Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-art-frame-01', + deviceName: 'Art Frame', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('art Frame', () => { + it('maps Art Frame device type to WoArtFrame', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Art Frame', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoArtFrame') + }) + + it('maps SwitchBot Art Frame device type to WoArtFrame', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Art Frame', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoArtFrame') + }) + + it('inherits color control methods from WoBulb', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Art Frame', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('setBrightness') + }) +}) diff --git a/test/devices/bot-password.test.ts b/test/devices/bot-password.test.ts new file mode 100644 index 00000000..c23d4f3d --- /dev/null +++ b/test/devices/bot-password.test.ts @@ -0,0 +1,112 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * test/bot-password.test.ts: Bot password support tests + */ + +import { Buffer } from 'node:buffer' + +import { describe, expect, it } from 'vitest' + +import { BOT_BLE_ACTIONS, buildBotBleCommand, parseBotBleResponse, validateBotPassword } from '../../src/utils/index.js' + +describe('bot Password Support', () => { + describe('validateBotPassword', () => { + it('accepts valid 4-character alphanumeric passwords', () => { + expect(() => validateBotPassword('A1b2')).not.toThrow() + expect(() => validateBotPassword('Test')).not.toThrow() + expect(() => validateBotPassword('1234')).not.toThrow() + expect(() => validateBotPassword('abcd')).not.toThrow() + expect(() => validateBotPassword('ABCD')).not.toThrow() + }) + + it('rejects passwords with invalid length', () => { + expect(() => validateBotPassword('abc')).toThrow('Invalid Bot password') + expect(() => validateBotPassword('abcde')).toThrow('Invalid Bot password') + expect(() => validateBotPassword('')).toThrow('Invalid Bot password') + }) + + it('rejects passwords with non-alphanumeric characters', () => { + expect(() => validateBotPassword('ab!2')).toThrow('Invalid Bot password') + expect(() => validateBotPassword('a b2')).toThrow('Invalid Bot password') + expect(() => validateBotPassword('ab-2')).toThrow('Invalid Bot password') + }) + + it('is case-sensitive', () => { + // Both should be valid but different + expect(() => validateBotPassword('AbCd')).not.toThrow() + expect(() => validateBotPassword('abcd')).not.toThrow() + }) + }) + + describe('buildBotBleCommand', () => { + it('builds plain commands without password', () => { + const pressCmd = buildBotBleCommand(BOT_BLE_ACTIONS.PRESS) + const onCmd = buildBotBleCommand(BOT_BLE_ACTIONS.TURN_ON) + const offCmd = buildBotBleCommand(BOT_BLE_ACTIONS.TURN_OFF) + + expect(pressCmd).toEqual(Buffer.from([0x57, 0x01, 0x00])) + expect(onCmd).toEqual(Buffer.from([0x57, 0x01, 0x01])) + expect(offCmd).toEqual(Buffer.from([0x57, 0x01, 0x02])) + }) + + it('builds encrypted commands with password', () => { + // Known test vector from homebridge-switchbot PR + const cmd = buildBotBleCommand(BOT_BLE_ACTIONS.TURN_ON, 'A1b2') + + expect(cmd.length).toBe(7) + expect(cmd[0]).toBe(0x57) // Command prefix + expect(cmd[1]).toBe(0x11) // Encrypted command indicator + expect(cmd).toEqual(Buffer.from([0x57, 0x11, 0xB8, 0x59, 0x37, 0x46, 0x01])) + }) + + it('generates different CRC32 for different passwords', () => { + const cmd1 = buildBotBleCommand(BOT_BLE_ACTIONS.PRESS, 'AbCd') + const cmd2 = buildBotBleCommand(BOT_BLE_ACTIONS.PRESS, 'abcd') + + // Same action (last byte), but different CRC32 (bytes 2-5) + expect(cmd1[6]).toBe(cmd2[6]) // Action byte same + expect(cmd1.subarray(2, 6).equals(cmd2.subarray(2, 6))).toBe(false) // CRC32 different + }) + + it('rejects invalid action codes', () => { + expect(() => buildBotBleCommand(0x99 as any)).toThrow('Invalid Bot BLE action') + }) + + it('validates password when provided', () => { + expect(() => buildBotBleCommand(BOT_BLE_ACTIONS.PRESS, 'abc')).toThrow('Invalid Bot password') + }) + }) + + describe('parseBotBleResponse', () => { + it('accepts success response (0x01)', () => { + const response = Buffer.from([0x01, 0x00, 0x00]) + expect(parseBotBleResponse(response)).toBe(true) + }) + + it('accepts encrypted success response (0x05)', () => { + const response = Buffer.from([0x05, 0x00, 0x00]) + expect(parseBotBleResponse(response)).toBe(true) + }) + + it('rejects invalid response length', () => { + const shortResponse = Buffer.from([0x01, 0x00]) + expect(() => parseBotBleResponse(shortResponse)).toThrow('Invalid Bot response length') + + const longResponse = Buffer.from([0x01, 0x00, 0x00, 0x00]) + expect(() => parseBotBleResponse(longResponse)).toThrow('Invalid Bot response length') + }) + + it('rejects error response codes', () => { + const errorResponse = Buffer.from([0x00, 0x00, 0x00]) + expect(() => parseBotBleResponse(errorResponse)).toThrow('Bot command failed') + }) + }) + + describe('bOT_BLE_ACTIONS constants', () => { + it('defines correct action values', () => { + expect(BOT_BLE_ACTIONS.PRESS).toBe(0x00) + expect(BOT_BLE_ACTIONS.TURN_ON).toBe(0x01) + expect(BOT_BLE_ACTIONS.TURN_OFF).toBe(0x02) + }) + }) +}) diff --git a/test/devices/bulb-color-temperature-bounds.test.ts b/test/devices/bulb-color-temperature-bounds.test.ts new file mode 100644 index 00000000..77ed911c --- /dev/null +++ b/test/devices/bulb-color-temperature-bounds.test.ts @@ -0,0 +1,104 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * test/bulb-color-temperature-bounds.test.ts: Bulb Color Temperature with Bounds Tests + */ + +import type { DeviceInfo } from '../../src/types/index.js' + +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { WoBulb } from '../../src/devices/wo-bulb.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-bulb', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('bulb color temperature with bounds (Task 6.3)', () => { + let bulb: WoBulb + let sendCommand: ReturnType + + beforeEach(() => { + bulb = new WoBulb(baseInfo()) + sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(bulb as any).sendCommand = sendCommand + }) + + it('should set color temperature with bounds', async () => { + const result = await bulb.setColorTemp(2700, 6500, 4000) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should clamp min/max temperature values', async () => { + const result = await bulb.setColorTemp(2000, 7000, 5000) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should ensure current temp is within min/max bounds', async () => { + const result = await bulb.setColorTemp(3000, 5000, 6500) // 6500 > max 5000 + expect(result).toBe(true) + // Temperature should be clamped to max (5000) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should handle reversed min/max temperatures', async () => { + const result = await bulb.setColorTemp(6500, 2700, 4000) // reversed + expect(result).toBe(true) + // Should auto-correct: min should be 2700, max should be 6500 + expect(sendCommand).toHaveBeenCalled() + }) + + it('should build correct BLE command structure', async () => { + await bulb.setColorTemp(2700, 6500, 4000) + + const callArgs = sendCommand.mock.calls[0] + const bleCommand = callArgs[0] + + // Command structure: [0x57, 0x0F, 0x47, 0x01, 0x17, BRIGHTNESS, MIN_KEL_HIGH, MIN_KEL_LOW, MAX_KEL_HIGH, MAX_KEL_LOW, TEMP_HIGH, TEMP_LOW] + expect(bleCommand[0]).toBe(0x57) + expect(bleCommand[1]).toBe(0x0F) + expect(bleCommand[2]).toBe(0x47) + expect(bleCommand[3]).toBe(0x01) + expect(bleCommand[4]).toBe(0x17) // color temp with bounds command + expect(bleCommand[5]).toBe(0x64) // brightness (default 100) + expect(bleCommand.length).toBe(12) // Base header (4) + cmd (1) + brightness (1) + min (2) + max (2) + temp (2) + }) + + it('should correctly encode temperature values as bytes', async () => { + await bulb.setColorTemp(2700, 6500, 4000) + + const callArgs = sendCommand.mock.calls[0] + const bleCommand = callArgs[0] + + // Min: 2700 = 0x0A8C -> high: 0x0A, low: 0x8C + expect(bleCommand[6]).toBe(0x0A) // min high + expect(bleCommand[7]).toBe(0x8C) // min low + + // Max: 6500 = 0x196C -> high: 0x19, low: 0x6C + expect(bleCommand[8]).toBe(0x19) // max high + expect(bleCommand[9]).toBe(0x64) // max low (0x64 is correct for 6500) + + // Current: 4000 = 0x0FA0 -> high: 0x0F, low: 0xA0 + expect(bleCommand[10]).toBe(0x0F) // temp high + expect(bleCommand[11]).toBe(0xA0) // temp low + }) + + it('should work with minimum valid temperature range', async () => { + const result = await bulb.setColorTemp(2700, 2700, 2700) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should work with maximum valid temperature range', async () => { + const result = await bulb.setColorTemp(6500, 6500, 6500) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) +}) diff --git a/test/devices/circulator-fan-variants.test.ts b/test/devices/circulator-fan-variants.test.ts new file mode 100644 index 00000000..62629ddd --- /dev/null +++ b/test/devices/circulator-fan-variants.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-fan-01', + deviceName: 'Circulator Fan', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('circulator fan variants', () => { + it('maps Battery Circulator Fan to WoCirculatorFan', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Battery Circulator Fan', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoCirculatorFan') + }) + + it('maps Circulator Fan to WoCirculatorFan', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Circulator Fan', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoCirculatorFan') + }) + + it('maps USB Circulator Fan to WoCirculatorFan', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'USB Circulator Fan', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoCirculatorFan') + }) + + it('inherits fan control methods', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Battery Circulator Fan', + }) + + const [device] = switchbot.devices.list() + expect(device).toBeDefined() + expect(typeof (device as any).turnOn).toBe('function') + expect(typeof (device as any).turnOff).toBe('function') + expect(typeof (device as any).setFanSpeed).toBe('function') + }) +}) diff --git a/test/devices/climate-panel-variants.test.ts b/test/devices/climate-panel-variants.test.ts new file mode 100644 index 00000000..288f86a6 --- /dev/null +++ b/test/devices/climate-panel-variants.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-climate-panel-01', + deviceName: 'Climate Panel', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('climate panel variants', () => { + it('maps Climate Panel to WoClimatePanel', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Climate Panel', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoClimatePanel') + }) + + it('maps Smart Climate Panel to WoClimatePanel', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Smart Climate Panel', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoClimatePanel') + }) + + it('inherits climate control methods', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Climate Panel', + }) + + const [device] = switchbot.devices.list() + expect(device).toBeDefined() + expect(typeof (device as any).turnOn).toBe('function') + expect(typeof (device as any).turnOff).toBe('function') + expect(typeof (device as any).setMode).toBe('function') + }) +}) diff --git a/test/devices/curtain3-features.test.ts b/test/devices/curtain3-features.test.ts new file mode 100644 index 00000000..707041cb --- /dev/null +++ b/test/devices/curtain3-features.test.ts @@ -0,0 +1,134 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * curtain3-features.test.ts: SwitchBot v4.0.0 - Curtain 3 Feature Tests + */ + +import { describe, expect, it } from 'vitest' + +import { WoCurtain } from '../../src/devices/wo-curtain.js' +import { SwitchBot } from '../../src/switchbot.js' + +describe('curtain 3 Features', () => { + it('should recognize Curtain3 device type', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + deviceId: 'curtain3-test-01', + deviceName: 'Curtain 3', + deviceType: 'Curtain3', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoCurtain') + // Device type remains as API device type 'Curtain3' + }) + + it('should have multi-command sequence method', () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + expect(curtain).toHaveProperty('sendCommandSequence') + expect(typeof curtain.sendCommandSequence).toBe('function') + }) + + it('should have multiple commands method', () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + expect(curtain).toHaveProperty('sendMultipleCommands') + expect(typeof curtain.sendMultipleCommands).toBe('function') + }) + + it('should have getExtendedInfo method', () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['ble'], + }) + + expect(curtain).toHaveProperty('getExtendedInfo') + expect(typeof curtain.getExtendedInfo).toBe('function') + }) + + it('should execute command sequence with all commands succeeding', async () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + const commands = [ + async () => true, // Simulated successful command + async () => true, // Simulated successful command + ] + + const result = await curtain.sendCommandSequence(commands) + expect(result).toBe(true) + }) + + it('should stop command sequence when a command fails', async () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + const commands = [ + async () => true, // Simulated successful command + async () => false, // Simulated failed command + async () => true, // Should not be executed + ] + + const result = await curtain.sendCommandSequence(commands) + expect(result).toBe(false) + }) + + it('should return true from sendMultipleCommands if any succeed', async () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + const commands = [ + async () => false, // Simulated failed command + async () => true, // Simulated successful command + async () => false, // Simulated failed command + ] + + const result = await curtain.sendMultipleCommands(commands) + expect(result).toBe(true) + }) + + it('should return false from sendMultipleCommands if all fail', async () => { + const curtain = new WoCurtain({ + id: 'curtain3-01', + name: 'Test Curtain 3', + deviceType: 'WoCurtain', + connectionTypes: ['api'], + }) + + const commands = [ + async () => false, // Simulated failed command + async () => false, // Simulated failed command + ] + + const result = await curtain.sendMultipleCommands(commands) + expect(result).toBe(false) + }) +}) diff --git a/test/devices/device-manager.test.ts b/test/devices/device-manager.test.ts new file mode 100644 index 00000000..ce841534 --- /dev/null +++ b/test/devices/device-manager.test.ts @@ -0,0 +1,108 @@ +import { beforeEach, describe, expect, it } from 'vitest' + +import { DeviceManager } from '../../src/devices/base.js' +import { WoHand } from '../../src/devices/wo-hand.js' + +describe('deviceManager', () => { + let manager: DeviceManager + + beforeEach(() => { + manager = new DeviceManager() + }) + + it('should add and retrieve devices', () => { + const device = new WoHand({ + id: 'test-device-1', + name: 'Test Bot', + deviceType: 'WoHand', + connectionTypes: ['ble', 'api'], + }) + + manager.add(device) + const retrieved = manager.get('test-device-1') + + expect(retrieved).toBeDefined() + expect(retrieved?.getId()).toBe('test-device-1') + expect(retrieved?.getName()).toBe('Test Bot') + }) + + it('should list all devices', () => { + const device1 = new WoHand({ + id: 'test-1', + name: 'Bot 1', + deviceType: 'WoHand', + connectionTypes: ['ble'], + }) + + const device2 = new WoHand({ + id: 'test-2', + name: 'Bot 2', + deviceType: 'WoHand', + connectionTypes: ['api'], + }) + + manager.add(device1) + manager.add(device2) + + const devices = manager.list() + expect(devices).toHaveLength(2) + expect(devices.map(d => d.getId())).toContain('test-1') + expect(devices.map(d => d.getId())).toContain('test-2') + }) + + it('should get count of devices', () => { + expect(manager.count()).toBe(0) + + manager.add(new WoHand({ + id: 'test-1', + name: 'Bot 1', + deviceType: 'WoHand', + connectionTypes: ['ble'], + })) + + expect(manager.count()).toBe(1) + }) + + it('should clear all devices', () => { + manager.add(new WoHand({ + id: 'test-1', + name: 'Bot 1', + deviceType: 'WoHand', + connectionTypes: ['ble'], + })) + + expect(manager.count()).toBe(1) + manager.clear() + expect(manager.count()).toBe(0) + }) + + it('should update existing device when adding duplicate id', () => { + const device1 = new WoHand({ + id: 'test-1', + name: 'Bot 1', + deviceType: 'WoHand', + connectionTypes: ['ble'], + }) + + const device2 = new WoHand({ + id: 'test-1', + name: 'Bot 1 Updated', + deviceType: 'WoHand', + connectionTypes: ['api'], + }) + + manager.add(device1) + expect(manager.count()).toBe(1) + + manager.add(device2) + expect(manager.count()).toBe(1) + + const retrieved = manager.get('test-1') + expect(retrieved?.getName()).toBe('Bot 1 Updated') + }) + + it('should return undefined for non-existent device', () => { + const device = manager.get('non-existent') + expect(device).toBeUndefined() + }) +}) diff --git a/test/devices/device-override-state-during-connection.test.ts b/test/devices/device-override-state-during-connection.test.ts new file mode 100644 index 00000000..4fa67aea --- /dev/null +++ b/test/devices/device-override-state-during-connection.test.ts @@ -0,0 +1,84 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoHand } from '../../src/devices/wo-hand.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-bot-override', + name: 'Test Bot Override', + deviceType: 'WoHand', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + bleServiceData: { + model: 'H', + modelName: 'WoHand', + state: false, + battery: 55, + }, + battery: 55, + rssi: -70, + } +} + +describe('device override state during connection', () => { + it('ignores advertisement bleServiceData updates while connected', () => { + const bleConnection = { + isConnected: vi.fn().mockReturnValue(true), + } as any + + const bot = new WoHand(baseInfo(), { bleConnection }) + + bot.updateInfo({ + bleServiceData: { + model: 'H', + modelName: 'WoHand', + state: true, + battery: 99, + }, + battery: 99, + rssi: -45, + }) + + const info = bot.getInfo() + expect(info.bleServiceData?.state).toBe(false) + expect(info.battery).toBe(55) + expect(info.rssi).toBe(-70) + }) + + it('accepts advertisement updates when not connected', () => { + const bleConnection = { + isConnected: vi.fn().mockReturnValue(false), + } as any + + const bot = new WoHand(baseInfo(), { bleConnection }) + + bot.updateInfo({ + bleServiceData: { + model: 'H', + modelName: 'WoHand', + state: true, + battery: 80, + }, + battery: 80, + rssi: -40, + }) + + const info = bot.getInfo() + expect(info.bleServiceData?.state).toBe(true) + expect(info.battery).toBe(80) + expect(info.rssi).toBe(-40) + }) + + it('returns empty fallback status payload while connected', () => { + const bleConnection = { + isConnected: vi.fn().mockReturnValue(true), + } as any + + const bot = new WoHand(baseInfo(), { bleConnection }) + + const normalized = (bot as any).normalizeBLEStatusData(undefined) + expect(normalized).toEqual({}) + }) +}) diff --git a/test/devices/floor-lamp.test.ts b/test/devices/floor-lamp.test.ts new file mode 100644 index 00000000..26bb6cd4 --- /dev/null +++ b/test/devices/floor-lamp.test.ts @@ -0,0 +1,56 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * floor-lamp.test.ts: SwitchBot v4.0.0 - Floor Lamp Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-floor-lamp-01', + deviceName: 'Floor Lamp', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('floor Lamp', () => { + it('maps Floor Lamp device type to WoFloorLamp', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoFloorLamp') + }) + + it('maps SwitchBot Floor Lamp device type to WoFloorLamp', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoFloorLamp') + }) + + it('inherits color control methods from WoBulb', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('setBrightness') + }) +}) diff --git a/test/devices/get-basic-info.test.ts b/test/devices/get-basic-info.test.ts new file mode 100644 index 00000000..4d852a9b --- /dev/null +++ b/test/devices/get-basic-info.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, it, vi } from 'vitest' + +import { SwitchBotDevice } from '../../src/devices/base.js' + +// Minimal mock device class for testing + +class TestDevice extends SwitchBotDevice { + constructor(options: any = {}) { + super({ + id: 'test', + name: 'Test Device', + deviceType: 'TestType', + mac: '00:11:22:33:44:55', + model: 'TestModel', + battery: 100, + connectionTypes: ['ble', 'api'], + }, options) + } + + async getStatus() { + return { + deviceId: 'test', + connectionType: 'ble' as const, + version: '1.0.0', + battery: 100, + updatedAt: new Date(), + } + } + + // Expose protected methods for mocking + setSendBLECommand(fn: any) { this.sendBLECommand = fn } + setSendAPICommand(fn: any) { this.sendAPICommand = fn } +} + +describe('switchBotDevice.getBasicInfo', () => { + it('returns BLE info if BLE is available', async () => { + const device = new TestDevice() + device.hasBLE = () => true + device.hasAPI = () => false + const bleMock = vi.fn().mockImplementation((cmd) => { + expect(cmd).toEqual([0x57, 0x02]) + return Promise.resolve({ + success: true, + data: { battery: 90, firmware: '2.0.0', extra: 'ble' }, + connectionType: 'ble', + }) + }) + device.setSendBLECommand(bleMock) + const result = await device.getBasicInfo() + expect(result.success).toBe(true) + expect(result.connectionType).toBe('ble') + expect(result.data.battery).toBe(90) + expect(result.data.firmware).toBe('2.0.0') + expect(result.data.extra).toBe('ble') + expect(bleMock).toHaveBeenCalledWith([0x57, 0x02]) + }) + + it('returns API info if API is available', async () => { + const device = new TestDevice() + device.hasBLE = () => false + device.hasAPI = () => true + const apiMock = vi.fn().mockImplementation((cmd) => { + expect(cmd).toBe('getBasicInfo') + return Promise.resolve({ + success: true, + data: { battery: 80, firmware: '3.0.0', extra: 'api' }, + connectionType: 'api', + }) + }) + device.setSendAPICommand(apiMock) + const result = await device.getBasicInfo() + expect(result.success).toBe(true) + expect(result.connectionType).toBe('api') + expect(result.data.battery).toBe(80) + expect(result.data.firmware).toBe('3.0.0') + expect(result.data.extra).toBe('api') + expect(apiMock).toHaveBeenCalledWith('getBasicInfo') + }) + + it('throws if no connection is available', async () => { + const device = new TestDevice() + device.hasBLE = () => false + device.hasAPI = () => false + await expect(device.getBasicInfo()).rejects.toThrow('No available connection for getBasicInfo') + }) +}) diff --git a/test/devices/hub3.test.ts b/test/devices/hub3.test.ts new file mode 100644 index 00000000..d08d2f08 --- /dev/null +++ b/test/devices/hub3.test.ts @@ -0,0 +1,55 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * hub3.test.ts: SwitchBot v4.0.0 - Hub 3 Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-hub3-01', + deviceName: 'Hub 3', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', +} + +describe('hub 3', () => { + it('maps Hub 3 device type to WoHub3', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Hub 3', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoHub3') + }) + + it('maps SwitchBot Hub 3 device type to WoHub3', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Hub 3', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoHub3') + }) + + it('inherits getStatus() from WoHub2', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Hub 3', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('getStatus') + expect(typeof device?.getStatus).toBe('function') + }) +}) diff --git a/test/devices/hubmini-matter.test.ts b/test/devices/hubmini-matter.test.ts new file mode 100644 index 00000000..4750de9e --- /dev/null +++ b/test/devices/hubmini-matter.test.ts @@ -0,0 +1,55 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * hubmini-matter.test.ts: SwitchBot v4.0.0 - HubMini Matter Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-hubmini-matter-01', + deviceName: 'HubMini Matter', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', +} + +describe('hubMini Matter', () => { + it('maps HubMini Matter device type to WoHubMiniMatter', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'HubMini Matter', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoHubMiniMatter') + }) + + it('maps SwitchBot HubMini Matter device type to WoHubMiniMatter', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '', logLevel: 0 }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot HubMini Matter', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoHubMiniMatter') + }) + + it('inherits getStatus() from WoHub2', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'HubMini Matter', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('getStatus') + expect(typeof device?.getStatus).toBe('function') + }) +}) diff --git a/test/devices/humidifier-level-control.test.ts b/test/devices/humidifier-level-control.test.ts new file mode 100644 index 00000000..1e77ccef --- /dev/null +++ b/test/devices/humidifier-level-control.test.ts @@ -0,0 +1,57 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoHumi2 } from '../../src/devices/wo-humi2.js' +import { WoHumi } from '../../src/devices/wo-humi.js' + +function humidifierInfo(): DeviceInfo { + return { + id: 'humi-01', + name: 'Humidifier', + deviceType: 'Humidifier', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('humidifier level control', () => { + it('woHumi setLevel delegates to setEfficiency', async () => { + const humidifier = new WoHumi(humidifierInfo()) + const setEfficiency = vi.fn().mockResolvedValue(true) + ;(humidifier as any).setEfficiency = setEfficiency + + const result = await humidifier.setLevel(65) + + expect(result).toBe(true) + expect(setEfficiency).toHaveBeenCalledWith(65) + }) + + it('woHumi setLevel clamps to 1-100', async () => { + const humidifier = new WoHumi(humidifierInfo()) + const setEfficiency = vi.fn().mockResolvedValue(true) + ;(humidifier as any).setEfficiency = setEfficiency + + await humidifier.setLevel(0) + await humidifier.setLevel(200) + + expect(setEfficiency).toHaveBeenNthCalledWith(1, 1) + expect(setEfficiency).toHaveBeenNthCalledWith(2, 100) + }) + + it('woHumi2 setLevel remains available through inheritance', async () => { + const humidifier = new WoHumi2({ + ...humidifierInfo(), + id: 'humi2-01', + deviceType: 'Humidifier 2', + }) + + const setEfficiency = vi.fn().mockResolvedValue(true) + ;(humidifier as any).setEfficiency = setEfficiency + + const result = await humidifier.setLevel(42) + + expect(result).toBe(true) + expect(setEfficiency).toHaveBeenCalledWith(42) + }) +}) diff --git a/test/devices/humidifier-mode-control.test.ts b/test/devices/humidifier-mode-control.test.ts new file mode 100644 index 00000000..8a87dcc1 --- /dev/null +++ b/test/devices/humidifier-mode-control.test.ts @@ -0,0 +1,73 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoHumi2 } from '../../src/devices/wo-humi2.js' +import { WoHumi } from '../../src/devices/wo-humi.js' + +function humidifierInfo(): DeviceInfo { + return { + id: 'humi-01', + name: 'Humidifier', + deviceType: 'Humidifier', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('humidifier mode control', () => { + it('woHumi setAuto delegates to setMode auto', async () => { + const humidifier = new WoHumi(humidifierInfo()) + const setMode = vi.fn().mockResolvedValue({ success: true }) + ;(humidifier as any).setMode = setMode + + const result = await humidifier.setAuto() + + expect(result).toBe(true) + expect(setMode).toHaveBeenCalledWith('auto') + }) + + it('woHumi setManual delegates to setMode manual', async () => { + const humidifier = new WoHumi(humidifierInfo()) + const setMode = vi.fn().mockResolvedValue({ success: true }) + ;(humidifier as any).setMode = setMode + + const result = await humidifier.setManual() + + expect(result).toBe(true) + expect(setMode).toHaveBeenCalledWith('manual') + }) + + it('woHumi getTargetLevel returns API humidity', async () => { + const humidifier = new WoHumi(humidifierInfo()) + ;(humidifier as any).hasAPI = () => true + ;(humidifier as any).getAPIStatus = vi.fn().mockResolvedValue({ humidity: 55 }) + + const result = await humidifier.getTargetLevel() + expect(result).toBe(55) + }) + + it('woHumi getTargetLevel returns BLE percentage', async () => { + const humidifier = new WoHumi(humidifierInfo()) + ;(humidifier as any).hasAPI = () => false + ;(humidifier as any).hasBLE = () => true + ;(humidifier as any).getBLEStatus = vi.fn().mockResolvedValue({ percentage: 42 }) + + const result = await humidifier.getTargetLevel() + expect(result).toBe(42) + }) + + it('woHumi2 inherits setAuto, setManual, getTargetLevel', async () => { + const humidifier = new WoHumi2({ ...humidifierInfo(), id: 'humi2-01', deviceType: 'Humidifier 2' }) + const setMode = vi.fn().mockResolvedValue(true) + ;(humidifier as any).setMode = setMode + await humidifier.setAuto() + expect(setMode).toHaveBeenCalledWith('auto') + await humidifier.setManual() + expect(setMode).toHaveBeenCalledWith('manual') + ;(humidifier as any).hasAPI = () => true + ;(humidifier as any).getAPIStatus = vi.fn().mockResolvedValue({ humidity: 77 }) + const result = await humidifier.getTargetLevel() + expect(result).toBe(77) + }) +}) diff --git a/test/devices/humidifier2-enhancement.test.ts b/test/devices/humidifier2-enhancement.test.ts new file mode 100644 index 00000000..03f929ba --- /dev/null +++ b/test/devices/humidifier2-enhancement.test.ts @@ -0,0 +1,67 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoHumi2 } from '../../src/devices/wo-humi2.js' +import { SwitchBot } from '../../src/switchbot.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-humi2', + name: 'Test Humidifier 2', + deviceType: 'Humidifier 2', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('humidifier 2 enhancement', () => { + it('setAuto delegates to setMode auto', async () => { + const humidifier = new WoHumi2(baseInfo()) + const setMode = vi.fn().mockResolvedValue({ success: true }) + ;(humidifier as any).setMode = setMode + + const result = await humidifier.setAuto() + + expect(result).toBe(true) + expect(setMode).toHaveBeenCalledWith('auto') + }) + + it('setManual delegates to setMode manual', async () => { + const humidifier = new WoHumi2(baseInfo()) + const setMode = vi.fn().mockResolvedValue({ success: true }) + ;(humidifier as any).setMode = setMode + + const result = await humidifier.setManual() + + expect(result).toBe(true) + expect(setMode).toHaveBeenCalledWith('manual') + }) + + it('setLevel delegates to setEfficiency', async () => { + const humidifier = new WoHumi2(baseInfo()) + const setEfficiency = vi.fn().mockResolvedValue(true) + ;(humidifier as any).setEfficiency = setEfficiency + + const result = await humidifier.setLevel(65) + + expect(result).toBe(true) + expect(setEfficiency).toHaveBeenCalledWith(65) + }) + + it('maps Evaporative Humidifier (Auto-refill) to WoHumi2', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + deviceId: 'api-humi2-01', + deviceName: 'Humidifier', + deviceType: 'Evaporative Humidifier (Auto-refill)', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoHumi2') + }) +}) diff --git a/test/devices/keypad-vision-pro.test.ts b/test/devices/keypad-vision-pro.test.ts new file mode 100644 index 00000000..ed39d21b --- /dev/null +++ b/test/devices/keypad-vision-pro.test.ts @@ -0,0 +1,55 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * keypad-vision-pro.test.ts: SwitchBot v4.0.0 - Keypad Vision Pro Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-keypad-vision-pro-01', + deviceName: 'Keypad Vision Pro', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', +} + +describe('keypad Vision Pro', () => { + it('maps Keypad Vision Pro device type to WoKeypadVisionPro', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Keypad Vision Pro', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoKeypadVisionPro') + }) + + it('maps SwitchBot Keypad Vision Pro device type to WoKeypadVisionPro', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Keypad Vision Pro', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoKeypadVisionPro') + }) + + it('inherits getStatus() from WoKeypad', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Keypad Vision Pro', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('getStatus') + expect(typeof device?.getStatus).toBe('function') + }) +}) diff --git a/test/devices/keypad-vision.test.ts b/test/devices/keypad-vision.test.ts new file mode 100644 index 00000000..303dd3d2 --- /dev/null +++ b/test/devices/keypad-vision.test.ts @@ -0,0 +1,54 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * keypad-vision.test.ts: SwitchBot v4.0.0 - Keypad Vision Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-keypad-vision-01', + deviceName: 'Keypad Vision', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', +} + +describe('keypad Vision', () => { + it('maps Keypad Vision device type to WoKeypadVision', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Keypad Vision', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoKeypadVision') + }) + + it('maps SwitchBot Keypad Vision device type to WoKeypadVision', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Keypad Vision', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoKeypadVision') + }) + + it('inherits keypad methods from WoKeypad', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Keypad Vision', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('getStatus') + }) +}) diff --git a/test/devices/light-multi-command.test.ts b/test/devices/light-multi-command.test.ts new file mode 100644 index 00000000..1059f647 --- /dev/null +++ b/test/devices/light-multi-command.test.ts @@ -0,0 +1,137 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * light-multi-command.test.ts: SwitchBot v4.0.0 - Light Multi-Command Sequence Tests + */ + +import { describe, expect, it } from 'vitest' + +import { WoBulb } from '../../src/devices/wo-bulb.js' +import { WoStripLight3 } from '../../src/devices/wo-strip-light-3.js' + +describe('light Multi-Command Sequences', () => { + it('should have sendCommandSequence method on WoBulb', () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + expect(bulb).toHaveProperty('sendCommandSequence') + expect(typeof bulb.sendCommandSequence).toBe('function') + }) + + it('should have sendMultipleCommands method on WoBulb', () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + expect(bulb).toHaveProperty('sendMultipleCommands') + expect(typeof bulb.sendMultipleCommands).toBe('function') + }) + + it('should have methods on Strip Light 3', () => { + const strip = new WoStripLight3({ + id: 'strip-01', + name: 'Test Strip', + deviceType: 'WoBulb', + connectionTypes: ['api'], + }) + + expect(strip).toHaveProperty('sendCommandSequence') + expect(strip).toHaveProperty('sendMultipleCommands') + }) + + it('should execute command sequence with all commands succeeding', async () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + const commands = [ + async () => true, // Simulated successful command + async () => true, // Simulated successful command + async () => true, // Simulated successful command + ] + + const result = await bulb.sendCommandSequence(commands) + expect(result).toBe(true) + }) + + it('should stop command sequence when a command fails', async () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + const commands = [ + async () => true, // Simulated successful command + async () => false, // Simulated failed command + async () => true, // Should not be executed + ] + + const result = await bulb.sendCommandSequence(commands) + expect(result).toBe(false) + }) + + it('should return true from sendMultipleCommands if any succeed', async () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + const commands = [ + async () => false, // Simulated failed command + async () => true, // Simulated successful command + async () => false, // Simulated failed command + ] + + const result = await bulb.sendMultipleCommands(commands) + expect(result).toBe(true) + }) + + it('should return false from sendMultipleCommands if all fail', async () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + const commands = [ + async () => false, // Simulated failed command + async () => false, // Simulated failed command + ] + + const result = await bulb.sendMultipleCommands(commands) + expect(result).toBe(false) + }) + + it('should execute complex light pattern with sequence', async () => { + const bulb = new WoBulb({ + id: 'bulb-01', + name: 'Test Bulb', + deviceType: 'Color Bulb', + connectionTypes: ['api'], + }) + + // Simulate a complex pattern: turn on, set brightness, set color + const commands = [ + async () => true, // turnOn + async () => true, // setBrightness + async () => true, // setColor + ] + + const result = await bulb.sendCommandSequence(commands) + expect(result).toBe(true) + }) +}) diff --git a/test/devices/lock-variants.test.ts b/test/devices/lock-variants.test.ts new file mode 100644 index 00000000..2eaa09e9 --- /dev/null +++ b/test/devices/lock-variants.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-lock-01', + deviceName: 'Lock', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('lock model variants', () => { + it('maps Lock Lite to WoSmartLockLite', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Lite', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartLockLite') + }) + + it('maps Lock Vision to WoSmartLockVision', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Vision', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartLockVision') + }) + + it('maps Lock Vision Pro to WoSmartLockVisionPro', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Vision Pro', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartLockVisionPro') + }) + + it('maps Lock Pro WiFi to WoSmartLockProWiFi', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Pro WiFi', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartLockProWiFi') + }) + + it('inherits lock() method from WoSmartLock', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Lite', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('lock') + expect(device).toHaveProperty('unlock') + }) + + it('inherits unlatch() method from WoSmartLockPro for pro variants', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Lock Vision Pro', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('lock') + expect(device).toHaveProperty('unlock') + expect(device).toHaveProperty('unlatch') + }) +}) diff --git a/test/devices/passive-polling.test.ts b/test/devices/passive-polling.test.ts new file mode 100644 index 00000000..9ec2ee89 --- /dev/null +++ b/test/devices/passive-polling.test.ts @@ -0,0 +1,75 @@ +import type { ConnectionType, DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { PASSIVE_POLL_INTERVAL, SwitchBotDevice } from '../../src/devices/base.js' +// + +class TestDevice extends SwitchBotDevice { + // Expose a protected setter for lastPolledAt for testing + setLastPolledAt(ts: number) { + // @ts-expect-error: test access + this.lastPolledAt = ts + } + + async getStatus() { + return { + deviceId: this.info.id, + connectionType: 'ble' as ConnectionType, + version: '1.0.0', + battery: 100, + updatedAt: new Date(), + } + } +} + +describe('switchbotdevice passive polling', () => { + const info: DeviceInfo = { + id: 'test', + name: 'Test Device', + deviceType: 'Test', + mac: '00:00:00:00:00:00', + connectionTypes: ['ble', 'api'], + activeConnection: 'ble', + } + + it('should require polling if never polled', () => { + const device = new TestDevice(info) + expect(device.pollNeeded()).toBe(true) + }) + + it('should not require polling if interval not elapsed', () => { + const device = new TestDevice(info) + device.setLastPolledAt(Date.now()) + expect(device.pollNeeded()).toBe(false) + }) + + it('should require polling if interval elapsed', () => { + const device = new TestDevice(info) + device.setLastPolledAt(Date.now() - (PASSIVE_POLL_INTERVAL + 1000)) + expect(device.pollNeeded()).toBe(true) + }) + + it('pollIfNeeded should call getStatus if needed', async () => { + const device = new TestDevice(info) + device.setLastPolledAt(Date.now() - (PASSIVE_POLL_INTERVAL + 1000)) + const status = await device.pollIfNeeded() + expect(status).toMatchObject({ + deviceId: 'test', + connectionType: 'ble', + version: '1.0.0', + battery: 100, + }) + // @ts-expect-error: test access + expect(typeof device.lastPolledAt).toBe('number') + }) + + it('pollIfNeeded should not call getStatus if not needed', async () => { + const device = new TestDevice(info) + device.setLastPolledAt(Date.now()) + const spy = vi.spyOn(device, 'getStatus') + const status = await device.pollIfNeeded() + expect(status).toBeUndefined() + expect(spy).not.toHaveBeenCalled() + }) +}) diff --git a/test/devices/plug-mini-eu.test.ts b/test/devices/plug-mini-eu.test.ts new file mode 100644 index 00000000..ce1798d5 --- /dev/null +++ b/test/devices/plug-mini-eu.test.ts @@ -0,0 +1,45 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * plug-mini-eu.test.ts: SwitchBot v4.0.0 - Plug Mini EU Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-plug-mini-eu-01', + deviceName: 'Plug Mini EU', + enableCloudService: true, + hubDeviceId: '', + version: 'V1.0', +} + +describe('plug Mini EU', () => { + it('maps Plug Mini (EU) device type to WoPlugMiniUS', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Plug Mini (EU)', + }) + + const [device] = switchbot.devices.list() + // WoPlugMiniEU is aliased to WoPlugMiniUS in the registry + expect(device?.constructor.name).toBe('WoPlugMiniUS') + }) + + it('inherits plug control methods from WoPlugMiniUS', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Plug Mini (EU)', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('toggle') + }) +}) diff --git a/test/devices/relay-2pm-channel-control.test.ts b/test/devices/relay-2pm-channel-control.test.ts new file mode 100644 index 00000000..a4c64cc3 --- /dev/null +++ b/test/devices/relay-2pm-channel-control.test.ts @@ -0,0 +1,87 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * test/relay-2pm-channel-control.test.ts: Relay Switch 2PM Channel Control Tests + */ +import { Buffer } from 'node:buffer' + +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { WoRelaySwitch2PM } from '../../src/devices/wo-relay-switch-2pm.js' +import { DEVICE_COMMANDS } from '../../src/settings.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-relay-2pm', + name: 'Test Relay 2PM', + deviceType: 'Relay Switch 2PM', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('relay switch 2PM channel control (Task 5.3)', () => { + let relay: WoRelaySwitch2PM + let sendCommand: ReturnType + + beforeEach(() => { + relay = new WoRelaySwitch2PM(baseInfo()) + sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(relay as any).sendCommand = sendCommand + }) + + it('should set channel 1 ON', async () => { + const result = await relay.setChannel1(true) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL1_ON), + 'setChannel1:true', + ) + }) + + it('should set channel 1 OFF', async () => { + const result = await relay.setChannel1(false) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL1_OFF), + 'setChannel1:false', + ) + }) + + it('should set channel 2 ON', async () => { + const result = await relay.setChannel2(true) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL2_ON), + 'setChannel2:true', + ) + }) + + it('should set channel 2 OFF', async () => { + const result = await relay.setChannel2(false) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL2_OFF), + 'setChannel2:false', + ) + }) + + it('should verify correct channel command bytes', () => { + // Verify command constants + expect(DEVICE_COMMANDS.RELAY.CHANNEL1_ON).toEqual([0x57, 0x0F, 0x50, 0x01, 0x01]) + expect(DEVICE_COMMANDS.RELAY.CHANNEL1_OFF).toEqual([0x57, 0x0F, 0x50, 0x01, 0x02]) + expect(DEVICE_COMMANDS.RELAY.CHANNEL2_ON).toEqual([0x57, 0x0F, 0x50, 0x02, 0x01]) + expect(DEVICE_COMMANDS.RELAY.CHANNEL2_OFF).toEqual([0x57, 0x0F, 0x50, 0x02, 0x02]) + }) + + it('should handle both channels independently', async () => { + await relay.setChannel1(true) + await relay.setChannel2(false) + + const calls = sendCommand.mock.calls + expect(calls).toHaveLength(2) + expect(calls[0][0]).toEqual(Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL1_ON)) + expect(calls[1][0]).toEqual(Buffer.from(DEVICE_COMMANDS.RELAY.CHANNEL2_OFF)) + }) +}) diff --git a/test/devices/relay-encryption.test.ts b/test/devices/relay-encryption.test.ts new file mode 100644 index 00000000..808ecf51 --- /dev/null +++ b/test/devices/relay-encryption.test.ts @@ -0,0 +1,51 @@ +import { Buffer } from 'node:buffer' + +import { describe, expect, it, vi } from 'vitest' + +import { WoRelaySwitch1 } from '../../src/devices/wo-relay-switch-1.js' +import { DEVICE_COMMANDS } from '../../src/settings.js' + +const ENCRYPTION_KEY = '00112233445566778899aabbccddeeff' // 16 bytes hex +const ENCRYPTION_IV = '0102030405060708090a0b0c0d0e0f10' // 16 bytes hex + +describe('relay Switch 1 BLE encryption', () => { + it('sends encrypted command when encryptionKey is present', async () => { + const relay = new WoRelaySwitch1({ + id: 'test-relay', + name: 'Test Relay', + deviceType: 'Relay Switch 1', + connectionTypes: ['ble'], + encryptionKey: ENCRYPTION_KEY, + encryptionIV: ENCRYPTION_IV, + }) + const sent: Buffer[] = [] + ;(relay as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await relay.turnOn() + expect(sent.length).toBe(1) + // Encrypted command should start with 0x11 + expect(sent[0][0]).toBe(0x11) + // Should not match plain command + expect(sent[0].equals(Buffer.from(DEVICE_COMMANDS.COMMON.POWER_ON))).toBe(false) + }) + + it('sends plain command when encryptionKey is absent', async () => { + const relay = new WoRelaySwitch1({ + id: 'test-relay', + name: 'Test Relay', + deviceType: 'Relay Switch 1', + connectionTypes: ['ble'], + }) + const sent: Buffer[] = [] + ;(relay as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await relay.turnOn() + expect(sent.length).toBe(1) + expect(sent[0][0]).not.toBe(0x11) + expect(sent[0].equals(Buffer.from(DEVICE_COMMANDS.COMMON.POWER_ON))).toBe(true) + }) +}) diff --git a/test/devices/relay-variants.test.ts b/test/devices/relay-variants.test.ts new file mode 100644 index 00000000..ed61a711 --- /dev/null +++ b/test/devices/relay-variants.test.ts @@ -0,0 +1,66 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-relay-01', + deviceName: 'Relay', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('relay switch variants', () => { + it('maps Relay Switch 2PM to WoRelaySwitch2PM', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Relay Switch 2PM', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRelaySwitch2PM') + }) + + it('maps Garage Door Opener to WoGarageDoorOpener', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Garage Door Opener', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoGarageDoorOpener') + }) + + it('woRelaySwitch2PM has channel-specific methods', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Relay Switch 2PM', + }) + + const [device] = switchbot.devices.list() + expect(device).toBeDefined() + expect(typeof (device as any).setChannel1).toBe('function') + expect(typeof (device as any).setChannel2).toBe('function') + }) + + it('woGarageDoorOpener inherits relay switch methods', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Garage Door Opener', + }) + + const [device] = switchbot.devices.list() + expect(device).toBeDefined() + expect(typeof (device as any).turnOn).toBe('function') + expect(typeof (device as any).turnOff).toBe('function') + expect(typeof (device as any).toggle).toBe('function') + }) +}) diff --git a/test/devices/rgbic-bulb-segmented-control.test.ts b/test/devices/rgbic-bulb-segmented-control.test.ts new file mode 100644 index 00000000..a745ffba --- /dev/null +++ b/test/devices/rgbic-bulb-segmented-control.test.ts @@ -0,0 +1,195 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * test/rgbic-bulb-segmented-control.test.ts: RGBIC Bulb Segmented Control Tests + */ + +import type { DeviceInfo } from '../../src/types/index.js' + +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { WoRGBICBulb } from '../../src/devices/wo-rgbic-bulb.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-rgbic', + name: 'Test RGBIC Bulb', + deviceType: 'RGBICWW Strip Light', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('rgbic bulb segmented control (Task 6.2)', () => { + let rgbic: WoRGBICBulb + let sendCommand: ReturnType + + beforeEach(() => { + rgbic = new WoRGBICBulb(baseInfo()) + sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(rgbic as any).sendCommand = sendCommand + }) + + describe('setSegmentColor', () => { + it('should set color for individual segment', async () => { + const result = await rgbic.setSegmentColor(0, 255, 0, 0) // Red segment 0 + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([0x57, 0x0F, 0x47, 0x01, 0x13, 0, 255, 0, 0]), + 'setSegmentColor', + 'seg0:255:0:0', + ) + }) + + it('should clamp segment color values', async () => { + // Values > 255 should be clamped + const result = await rgbic.setSegmentColor(0, 300, -50, 256) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([0x57, 0x0F, 0x47, 0x01, 0x13, 0, 255, 0, 255]), + 'setSegmentColor', + 'seg0:255:0:255', + ) + }) + + it('should clamp segment id value', async () => { + // Segment ID > 255 should be clamped to 255 + const result = await rgbic.setSegmentColor(300, 100, 100, 100) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([255]), // segment id clamped to 255 + 'setSegmentColor', + 'seg255:100:100:100', + ) + }) + + it('should handle full RGB spectrum on segment', async () => { + const result = await rgbic.setSegmentColor(1, 0, 128, 255) // Blue-green + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([0x57, 0x0F, 0x47, 0x01, 0x13, 1, 0, 128, 255]), + 'setSegmentColor', + 'seg1:0:128:255', + ) + }) + + it('should support multiple segments sequentially', async () => { + await rgbic.setSegmentColor(0, 255, 0, 0) // Red + await rgbic.setSegmentColor(1, 0, 255, 0) // Green + await rgbic.setSegmentColor(2, 0, 0, 255) // Blue + + const calls = sendCommand.mock.calls + expect(calls).toHaveLength(3) + expect(calls[0][2]).toBe('seg0:255:0:0') + expect(calls[1][2]).toBe('seg1:0:255:0') + expect(calls[2][2]).toBe('seg2:0:0:255') + }) + }) + + describe('setSegmentEffect', () => { + it('should set segment effect with speed control', async () => { + const result = await rgbic.setSegmentEffect(1, 'rainbow', 75) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([0x57, 0x0F, 0x47, 0x01, 0x14, 1, 0x06, 75]), // rainbow = 0x06 + 'setSegmentEffect', + 'seg1:rainbow:75', + ) + }) + + it('should support RGBIC-specific effects', async () => { + const rgbicEffects = [ + 'segment_cycle', + 'segment_wave', + 'segment_chase', + 'segment_strobe', + 'segment_twinkle', + ] + + for (const effect of rgbicEffects) { + const result = await rgbic.setSegmentEffect(0, effect, 50) + expect(result).toBe(true) + } + }) + + it('should throw on unsupported RGBIC effect', async () => { + await expect(rgbic.setSegmentEffect(0, 'unsupported_effect', 50)).rejects.toThrow( + 'Unsupported RGBIC effect: unsupported_effect', + ) + }) + + it('should clamp segment speed values', async () => { + // Speed > 100 should be clamped to 100 + const result = await rgbic.setSegmentEffect(0, 'rainbow', 150) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([100]), // speed clamped to 100 + 'setSegmentEffect', + 'seg0:rainbow:100', + ) + }) + + it('should enforce minimum speed value', async () => { + // Speed < 1 should be clamped to 1 + const result = await rgbic.setSegmentEffect(0, 'rainbow', -50) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + expect.arrayContaining([1]), // speed clamped to 1 + 'setSegmentEffect', + 'seg0:rainbow:1', + ) + }) + + it('should handle effect names case-insensitively', async () => { + const result = await rgbic.setSegmentEffect(0, 'RAINBOW', 50) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + }) + + describe('inheritance and compatibility', () => { + it('should support standard bulb effects on RGBIC', async () => { + const standardEffects = [ + 'christmas', + 'sunset', + 'rainbow', + 'ocean', + 'flicker', + ] + + for (const effect of standardEffects) { + const result = await rgbic.setEffect(effect, 80) + expect(result).toBe(true) + } + }) + + it('should support color temperature bounds inherited from WoBulb', async () => { + const result = await rgbic.setColorTemp(2700, 6500, 4000) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should support basic color setting inherited from WoBulb', async () => { + const result = await rgbic.setColor(255, 128, 64) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + + it('should support brightness control inherited from WoBulb', async () => { + const result = await rgbic.setBrightness(75) + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalled() + }) + }) + + describe('device instantiation', () => { + it('should create WoRGBICBulb with all segment commands', () => { + expect(rgbic).toBeDefined() + expect(typeof rgbic.setSegmentColor).toBe('function') + expect(typeof rgbic.setSegmentEffect).toBe('function') + expect(typeof rgbic.setColorTemp).toBe('function') + expect(typeof rgbic.setEffect).toBe('function') + expect(typeof rgbic.setColor).toBe('function') + expect(typeof rgbic.setBrightness).toBe('function') + }) + }) +}) diff --git a/test/devices/rgbicww-floor-lamp.test.ts b/test/devices/rgbicww-floor-lamp.test.ts new file mode 100644 index 00000000..ed8aca94 --- /dev/null +++ b/test/devices/rgbicww-floor-lamp.test.ts @@ -0,0 +1,57 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * rgbicww-floor-lamp.test.ts: SwitchBot v4.0.0 - RGBICWW Floor Lamp Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-rgbicww-floor-lamp-01', + deviceName: 'RGBICWW Floor Lamp', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('rgbicww Floor Lamp', () => { + it('maps RGBICWW Floor Lamp device type to WoRGBICWWFloorLamp', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'RGBICWW Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRGBICWWFloorLamp') + }) + + it('maps SwitchBot RGBICWW Floor Lamp device type to WoRGBICWWFloorLamp', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot RGBICWW Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRGBICWWFloorLamp') + }) + + it('inherits segmented control methods from WoRGBICBulb', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'RGBICWW Floor Lamp', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('setBrightness') + expect(device).toHaveProperty('setSegmentColor') + }) +}) diff --git a/test/devices/rgbicww-strip-light.test.ts b/test/devices/rgbicww-strip-light.test.ts new file mode 100644 index 00000000..311b6046 --- /dev/null +++ b/test/devices/rgbicww-strip-light.test.ts @@ -0,0 +1,52 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * rgbicww-strip-light.test.ts: SwitchBot v4.0.0 - RGBICWW Strip Light Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-rgbicww-strip-light-01', + deviceName: 'RGBICWW Strip Light', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('rgbicww Strip Light', () => { + // Remove non-async tests; only use async/await versions + it('maps RGBICWW Strip Light device type to WoRGBICWWStripLight', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'RGBICWW Strip Light', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRGBICWWStripLight') + }) + + it('maps SwitchBot RGBICWW Strip Light device type to WoRGBICWWStripLight', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot RGBICWW Strip Light', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRGBICWWStripLight') + }) + + it('inherits segmented control methods from WoRGBICBulb', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'RGBICWW Strip Light', + }) + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('setBrightness') + expect(device).toHaveProperty('setSegmentColor') + }) +}) diff --git a/test/devices/roller-shade.test.ts b/test/devices/roller-shade.test.ts new file mode 100644 index 00000000..c730a29f --- /dev/null +++ b/test/devices/roller-shade.test.ts @@ -0,0 +1,52 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * roller-shade.test.ts: SwitchBot v4.0.0 - Roller Shade Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-roller-shade-01', + deviceName: 'Roller Shade', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('roller Shade', () => { + // Remove non-async tests; only use async/await versions + it('maps Roller Shade device type to WoRollerShade', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Roller Shade', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRollerShade') + }) + + it('maps SwitchBot Roller Shade device type to WoRollerShade', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Roller Shade', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoRollerShade') + }) + + it('inherits curtain control methods from WoCurtain', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Roller Shade', + }) + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('open') + expect(device).toHaveProperty('close') + expect(device).toHaveProperty('pause') + expect(device).toHaveProperty('setPosition') + }) +}) diff --git a/test/devices/sequence-device.test.ts b/test/devices/sequence-device.test.ts new file mode 100644 index 00000000..9999b6cc --- /dev/null +++ b/test/devices/sequence-device.test.ts @@ -0,0 +1,123 @@ +import type { DeviceInfo, DeviceStatus } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { SequenceDevice } from '../../src/devices/sequence-device.js' + +function baseInfo(sequenceNumber?: number): DeviceInfo { + return { + id: 'test-sequence-device', + name: 'Test Sequence Device', + deviceType: 'WoSmartLock', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + bleServiceData: sequenceNumber === undefined + ? undefined + : { + model: 'o', + modelName: 'Smart Lock', + sequenceNumber, + }, + } +} + +class TestSequenceDevice extends SequenceDevice { + async getStatus(): Promise { + return { + deviceId: this.getId(), + connectionType: 'ble', + updatedAt: new Date(), + } + } +} + +describe('sequence device', () => { + it('does not trigger update when sequence number is unchanged', async () => { + const device = new TestSequenceDevice(baseInfo(12)) + const updateSpy = vi.spyOn(device, 'update').mockResolvedValue({ + deviceId: 'test-sequence-device', + connectionType: 'ble', + updatedAt: new Date(), + }) + + device.updateInfo({ + bleServiceData: { + model: 'o', + modelName: 'Smart Lock', + sequenceNumber: 12, + }, + }) + + await new Promise(resolve => setTimeout(resolve, 0)) + + expect(updateSpy).not.toHaveBeenCalled() + }) + + it('triggers update and emits sequence-changed on sequence increment', async () => { + const device = new TestSequenceDevice(baseInfo(1)) + const updateSpy = vi.spyOn(device, 'update').mockResolvedValue({ + deviceId: 'test-sequence-device', + connectionType: 'ble', + updatedAt: new Date(), + }) + const sequenceChanged = vi.fn() + + device.on('sequence-changed', sequenceChanged) + + device.updateInfo({ + bleServiceData: { + model: 'o', + modelName: 'Smart Lock', + sequenceNumber: 2, + }, + }) + + await new Promise(resolve => setTimeout(resolve, 0)) + + expect(updateSpy).toHaveBeenCalledTimes(1) + expect(sequenceChanged).toHaveBeenCalledTimes(1) + expect(sequenceChanged.mock.calls[0]?.[0]).toMatchObject({ + deviceId: 'test-sequence-device', + previousSequenceNumber: 1, + sequenceNumber: 2, + }) + }) + + it('suppresses additional sequence updates while one is in flight', async () => { + const device = new TestSequenceDevice(baseInfo(10)) + let resolveUpdate: (() => void) | undefined + const pendingUpdate = new Promise((resolve) => { + resolveUpdate = () => { + resolve({ + deviceId: 'test-sequence-device', + connectionType: 'ble', + updatedAt: new Date(), + }) + } + }) + + const updateSpy = vi.spyOn(device, 'update').mockReturnValue(pendingUpdate) + + device.updateInfo({ + bleServiceData: { + model: 'o', + modelName: 'Smart Lock', + sequenceNumber: 11, + }, + }) + + device.updateInfo({ + bleServiceData: { + model: 'o', + modelName: 'Smart Lock', + sequenceNumber: 12, + }, + }) + + await new Promise(resolve => setTimeout(resolve, 0)) + + expect(updateSpy).toHaveBeenCalledTimes(1) + resolveUpdate?.() + await pendingUpdate + }) +}) diff --git a/test/devices/set-mode.test.ts b/test/devices/set-mode.test.ts new file mode 100644 index 00000000..57dff7f6 --- /dev/null +++ b/test/devices/set-mode.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it, vi } from 'vitest' + +import { SwitchBotDevice } from '../../src/devices/base.js' + +// Minimal mock device class for testing +class TestDevice extends SwitchBotDevice { + constructor(options: any = {}) { + super({ + id: 'test', + name: 'Test Device', + deviceType: 'TestType', + mac: '00:11:22:33:44:55', + model: 'TestModel', + battery: 100, + connectionTypes: ['ble', 'api'], + }, options) + } + + async getStatus() { + return { + deviceId: 'test', + connectionType: 'ble' as const, + version: '1.0.0', + battery: 100, + updatedAt: new Date(), + } + } + + setSendBLECommand(fn: any) { (this as any).sendBLECommand = fn } + setSendAPICommand(fn: any) { (this as any).sendAPICommand = fn } +} + +describe('switchBotDevice.setMode', () => { + it('sends BLE command if BLE is available', async () => { + const device = new TestDevice() + device.hasBLE = () => true + device.hasAPI = () => false + device.setSendBLECommand(vi.fn().mockResolvedValue({ success: true, mode: 'auto' })) + const result = await device.setMode('auto') + expect(result.success).toBe(true) + expect((device as any).sendBLECommand).toHaveBeenCalledWith([0x57, 0x03, expect.any(Number)]) + }) + + it('sends API command if API is available', async () => { + const device = new TestDevice() + device.hasBLE = () => false + device.hasAPI = () => true + device.setSendAPICommand(vi.fn().mockResolvedValue({ success: true, mode: 'manual' })) + const result = await device.setMode('manual') + expect(result.success).toBe(true) + expect((device as any).sendAPICommand).toHaveBeenCalledWith('setMode', { mode: 'manual' }) + }) + + it('throws if no connection is available', async () => { + const device = new TestDevice() + device.hasBLE = () => false + device.hasAPI = () => false + await expect(device.setMode('auto')).rejects.toThrow('No available connection for setMode') + }) +}) diff --git a/test/devices/strip-encryption.test.ts b/test/devices/strip-encryption.test.ts new file mode 100644 index 00000000..6ce9a6b4 --- /dev/null +++ b/test/devices/strip-encryption.test.ts @@ -0,0 +1,49 @@ +import { Buffer } from 'node:buffer' + +import { describe, expect, it, vi } from 'vitest' + +import { WoStrip } from '../../src/devices/wo-strip.js' +import { DEVICE_COMMANDS } from '../../src/settings.js' + +const ENCRYPTION_KEY = '00112233445566778899aabbccddeeff' // 16 bytes hex +const ENCRYPTION_IV = '0102030405060708090a0b0c0d0e0f10' // 16 bytes hex + +describe('strip Light BLE encryption', () => { + it('sends encrypted command when encryptionKey is present', async () => { + const strip = new WoStrip({ + id: 'test-strip', + name: 'Test Strip', + deviceType: 'Strip Light', + connectionTypes: ['ble'], + encryptionKey: ENCRYPTION_KEY, + encryptionIV: ENCRYPTION_IV, + }) + const sent: Buffer[] = [] + ;(strip as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await strip.turnOn() + expect(sent.length).toBe(1) + expect(sent[0][0]).toBe(0x11) + expect(sent[0].equals(Buffer.from([...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.TURN_ON]))).toBe(false) + }) + + it('sends plain command when encryptionKey is absent', async () => { + const strip = new WoStrip({ + id: 'test-strip', + name: 'Test Strip', + deviceType: 'Strip Light', + connectionTypes: ['ble'], + }) + const sent: Buffer[] = [] + ;(strip as any).sendCommand = vi.fn(async (cmd: Buffer) => { + sent.push(cmd) + return { success: true } + }) + await strip.turnOn() + expect(sent.length).toBe(1) + expect(sent[0][0]).not.toBe(0x11) + expect(sent[0].equals(Buffer.from([...DEVICE_COMMANDS.BULB.BASE, ...DEVICE_COMMANDS.BULB.TURN_ON]))).toBe(true) + }) +}) diff --git a/test/devices/strip-light-3.test.ts b/test/devices/strip-light-3.test.ts new file mode 100644 index 00000000..53fcb805 --- /dev/null +++ b/test/devices/strip-light-3.test.ts @@ -0,0 +1,56 @@ +/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * strip-light-3.test.ts: SwitchBot v4.0.0 - Strip Light 3 Tests + */ + +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-strip-light-3-01', + deviceName: 'Strip Light 3', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('strip Light 3', () => { + it('maps Strip Light 3 device type to WoStripLight3', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Strip Light 3', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoStripLight3') + }) + + it('maps SwitchBot Strip Light 3 device type to WoStripLight3', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'SwitchBot Strip Light 3', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoStripLight3') + }) + + it('inherits color control methods from WoBulb', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Strip Light 3', + }) + + const [device] = switchbot.devices.list() + expect(device).toHaveProperty('turnOn') + expect(device).toHaveProperty('turnOff') + expect(device).toHaveProperty('setBrightness') + }) +}) diff --git a/test/devices/thermostat-radiator-variants.test.ts b/test/devices/thermostat-radiator-variants.test.ts new file mode 100644 index 00000000..b81f590d --- /dev/null +++ b/test/devices/thermostat-radiator-variants.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-thermostat-01', + deviceName: 'Thermostat', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('smart thermostat radiator variants', () => { + it('maps Smart Thermostat Radiator to WoSmartThermostatRadiator', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Smart Thermostat Radiator', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartThermostatRadiator') + }) + + it('maps Thermostat Radiator to WoSmartThermostatRadiator', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Thermostat Radiator', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartThermostatRadiator') + }) + + it('maps Radiator Thermostat to WoSmartThermostatRadiator', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Radiator Thermostat', + }) + + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoSmartThermostatRadiator') + }) + + it('inherits climate control methods', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Smart Thermostat Radiator', + }) + + const [device] = switchbot.devices.list() + expect(device).toBeDefined() + expect(typeof (device as any).turnOn).toBe('function') + expect(typeof (device as any).turnOff).toBe('function') + expect(typeof (device as any).setMode).toBe('function') + }) +}) diff --git a/test/devices/vacuum-commands.test.ts b/test/devices/vacuum-commands.test.ts new file mode 100644 index 00000000..e1015027 --- /dev/null +++ b/test/devices/vacuum-commands.test.ts @@ -0,0 +1,103 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +import { WoVacuum } from '../../src/devices/wo-vacuum.js' +import { DEVICE_COMMANDS } from '../../src/settings.js' + +function baseInfo(): DeviceInfo { + return { + id: 'test-vacuum', + name: 'Test Vacuum', + deviceType: 'Robot Vacuum Cleaner K10 Plus', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('vacuum commands', () => { + beforeEach(() => { + // Always mock hasBLE to return true for command tests + vi.spyOn(WoVacuum.prototype as any, 'hasBLE').mockReturnValue(true) + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('sends cleanup command with protocol version 1', async () => { + const vacuum = new WoVacuum(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(vacuum as any).sendCommand = sendCommand + + const result = await vacuum.cleanUp(1) + + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + DEVICE_COMMANDS.VACUUM.CLEAN_UP[1], + 'start', + { protocolVersion: 1 }, + ) + }) + + it('sends cleanup command with protocol version 2', async () => { + const vacuum = new WoVacuum(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(vacuum as any).sendCommand = sendCommand + + const result = await vacuum.cleanUp(2) + + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + DEVICE_COMMANDS.VACUUM.CLEAN_UP[2], + 'start', + { protocolVersion: 2 }, + ) + }) + + it('sends return-to-dock command with protocol version 1', async () => { + const vacuum = new WoVacuum(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(vacuum as any).sendCommand = sendCommand + + const result = await vacuum.returnToDock(1) + + expect(result).toBe(true) + expect(sendCommand).toHaveBeenCalledWith( + DEVICE_COMMANDS.VACUUM.RETURN_TO_DOCK[1], + 'dock', + { protocolVersion: 1 }, + ) + }) + + it('rejects unsupported protocol versions', async () => { + const vacuum = new WoVacuum(baseInfo()) + + await expect(vacuum.cleanUp(3)).rejects.toThrow('Unsupported vacuum protocol version: 3') + await expect(vacuum.returnToDock(0)).rejects.toThrow('Unsupported vacuum protocol version: 0') + }) +}) + +describe('vacuum status getters', () => { + it('returns status fields from BLE advertisement data', () => { + const vacuum = new WoVacuum(baseInfo()) + + ;(vacuum as any).updateInfo({ + bleServiceData: { + model: '\\x0F', + modelName: 'Robot Vacuum Cleaner K10 Plus', + battery: 88, + work_status: 2, + dustbin_bound: true, + dusbin_connected: false, + network_connected: true, + }, + }) + + expect(vacuum.getBattery()).toBe(88) + expect(vacuum.getWorkStatus()).toBe(2) + expect(vacuum.getDustbinBoundStatus()).toBe(true) + expect(vacuum.getDustbinConnectedStatus()).toBe(false) + expect(vacuum.getNetworkConnectedStatus()).toBe(true) + }) +}) diff --git a/test/devices/vacuum-variants.test.ts b/test/devices/vacuum-variants.test.ts new file mode 100644 index 00000000..2a9cb59b --- /dev/null +++ b/test/devices/vacuum-variants.test.ts @@ -0,0 +1,84 @@ +import { describe, expect, it } from 'vitest' + +import { SwitchBot } from '../../src/switchbot.js' + +const baseDevice = { + deviceId: 'api-vacuum-01', + deviceName: 'Vacuum', + enableCloudService: true, + hubDeviceId: 'hub-1', + version: 'V1.0', +} + +describe('vacuum model variants', () => { + // Remove non-async tests; only use async/await versions + it('maps K10+ to WoVacuumK10Plus', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner K10+', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumK10Plus') + }) + + it('maps K10+ Pro to WoVacuumK10Pro', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner K10+ Pro', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumK10Pro') + }) + + it('maps K10+ Pro Combo to WoVacuumK10ProCombo', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner K10+ Pro Combo', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumK10ProCombo') + }) + + it('maps K11+ to WoVacuumK11Plus', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner K11+', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumK11Plus') + }) + + it('maps K20 to WoVacuumK20', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner K20', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumK20') + }) + + it('maps S10 to WoVacuumS10', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner S10', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumS10') + }) + + it('maps S20 to WoVacuumS20', async () => { + const switchbot = new SwitchBot({ enableBLE: false, token: '', secret: '' }) + await (switchbot as any).handleAPIDiscovery({ + ...baseDevice, + deviceType: 'Robot Vacuum Cleaner S20', + }) + const [device] = switchbot.devices.list() + expect(device?.constructor.name).toBe('WoVacuumS20') + }) +}) diff --git a/test/devices/wo-blind-tilt.test.ts b/test/devices/wo-blind-tilt.test.ts new file mode 100644 index 00000000..c0e43a0d --- /dev/null +++ b/test/devices/wo-blind-tilt.test.ts @@ -0,0 +1,79 @@ +import type { ConnectionType, DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoBlindTilt } from '../../src/devices/wo-blind-tilt.js' + +describe('woBlindTilt Fallback Logic', () => { + const info: DeviceInfo = { + id: 'blind-tilt-1', + name: 'Test Blind Tilt', + deviceType: 'WoBlindTilt', + connectionTypes: ['ble', 'api'] as ConnectionType[], + mac: 'AA:BB:CC:DD:EE:11', + cloudServiceEnabled: true, + } + + it('prefers BLE for status if available', async () => { + // Only provide properties that WoBlindTilt.getStatus returns and match undefined for optional ones + const bleStatus = { + position: 50, + inMotion: false, + calibration: true, + battery: 80, + } + const expected = { + deviceId: 'blind-tilt-1', + connectionType: 'ble', + position: 50, + direction: undefined, + moving: false, + calibrated: true, + battery: 80, + } + const bleConnection = { read: vi.fn().mockResolvedValue(bleStatus) } as any + const apiClient = { getStatus: vi.fn().mockResolvedValue({ ...bleStatus }) } as any + const device = new WoBlindTilt(info, { bleConnection, apiClient }) + device.hasBLE = () => true + device.hasAPI = () => true + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).not.toHaveBeenCalled() + expect(status).toMatchObject(expected) + }) + + it('falls back to API if BLE fails', async () => { + // Only provide properties that WoBlindTilt.getStatus expects from API + const apiStatus = { + slidePosition: 50, + moving: false, + calibrate: true, + battery: 80, + } + const expected = { + deviceId: 'blind-tilt-1', + connectionType: 'api', + position: 50, + direction: undefined, + moving: false, + calibrated: true, + battery: 80, + } + const bleConnection = { read: vi.fn().mockRejectedValue(new Error('BLE error')) } as any + const apiClient = { getStatus: vi.fn().mockResolvedValue(apiStatus) } as any + const device = new WoBlindTilt(info, { bleConnection, apiClient }) + device.hasBLE = () => true + device.hasAPI = () => true + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).toHaveBeenCalled() + expect(status).toMatchObject(expected) + }) + + it('throws if both BLE and API fail', async () => { + const bleConnection = { read: vi.fn().mockRejectedValue(new Error('BLE error')) } as any + const apiClient = { getStatus: vi.fn().mockRejectedValue(new Error('API error')) } as any + const device = new WoBlindTilt(info, { bleConnection, apiClient }) + await expect(device.getStatus()).rejects.toThrow() + }) +}) diff --git a/test/devices/wo-bulb.test.ts b/test/devices/wo-bulb.test.ts new file mode 100644 index 00000000..92ab491b --- /dev/null +++ b/test/devices/wo-bulb.test.ts @@ -0,0 +1,26 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoBulb } from '../../src/devices/wo-bulb.js' + +function baseInfo(): DeviceInfo { + return { + id: 'WoBulb-1', + name: 'WoBulb', + deviceType: 'WoBulb', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('woBulb', () => { + it('supports bulb effect presets and rejects unknown effect', async () => { + const bulb = new WoBulb(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(bulb as any).sendCommand = sendCommand + + await expect(bulb.setEffect?.('rainbow', 20)).resolves.toBe(true) + await expect(bulb.setEffect?.('not-an-effect')).rejects.toThrow('Unsupported effect') + }) +}) diff --git a/test/devices/wo-hand.test.ts b/test/devices/wo-hand.test.ts new file mode 100644 index 00000000..b05740db --- /dev/null +++ b/test/devices/wo-hand.test.ts @@ -0,0 +1,31 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoHand } from '../../src/devices/wo-hand.js' + +function baseInfo(): DeviceInfo { + return { + id: 'WoHand-1', + name: 'WoHand', + deviceType: 'WoHand', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('woHand', () => { + it('supports bot mode configuration commands', async () => { + const bot = new WoHand(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(bot as any).sendCommand = sendCommand + + const modeResult = await bot.setMode?.('switch') + expect(modeResult?.success).toBe(true) + await expect(bot.setLongPress?.(50)).resolves.toBe(true) + await expect(bot.handUp?.()).resolves.toBe(true) + await expect(bot.handDown?.()).resolves.toBe(true) + + expect(sendCommand).toHaveBeenCalledTimes(4) + }) +}) diff --git a/test/devices/wo-lock.test.ts b/test/devices/wo-lock.test.ts new file mode 100644 index 00000000..d58b55de --- /dev/null +++ b/test/devices/wo-lock.test.ts @@ -0,0 +1,27 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoSmartLock } from '../../src/devices/wo-lock.js' + +function baseInfo(): DeviceInfo { + return { + id: 'WoSmartLock-1', + name: 'WoSmartLock', + deviceType: 'WoSmartLock', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('woSmartLock', () => { + it('skips lock command when state already matches target', async () => { + const lock = new WoSmartLock(baseInfo()) + const sendCommand = vi.fn().mockResolvedValue({ success: true }) + ;(lock as any).sendCommand = sendCommand + ;(lock as any).getStatus = vi.fn().mockResolvedValue({ lockState: 'locked' }) + + await expect(lock.lock()).resolves.toBe(true) + expect(sendCommand).not.toHaveBeenCalled() + }) +}) diff --git a/test/devices/wo-pan-tilt-cam-plus-3k.test.ts b/test/devices/wo-pan-tilt-cam-plus-3k.test.ts new file mode 100644 index 00000000..1105ab35 --- /dev/null +++ b/test/devices/wo-pan-tilt-cam-plus-3k.test.ts @@ -0,0 +1,77 @@ +import type { ConnectionType, DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoPanTiltCamPlus3K } from '../../src/devices/wo-pan-tilt-cam-plus-3k.js' + +// Minimal type-complete BLEConnection mock +function createBLEConnectionMock(overrides: Partial = {}) { + return { + noble: undefined, + logger: { error: () => {}, warn: () => {}, info: () => {}, debug: () => {} }, + connections: {}, + characteristics: {}, + read: vi.fn(), + ...overrides, + } +} + +// Minimal type-complete OpenAPIClient mock +function createAPIClientMock(overrides: Partial = {}) { + return { + logger: { error: () => {}, warn: () => {}, info: () => {}, debug: () => {} }, + token: '', + secret: '', + baseURL: '', + getStatus: vi.fn(), + ...overrides, + } +} + +describe('woPanTiltCamPlus3K Fallback Logic', () => { + const info: DeviceInfo = { + id: 'pan-tilt-cam-3k-1', + name: 'Test Pan Tilt Cam 3K', + deviceType: 'WoPanTiltCamPlus3K', + connectionTypes: ['ble', 'api'] as ConnectionType[], + mac: 'AA:BB:CC:DD:EE:33', + cloudServiceEnabled: true, + } + + it('prefers BLE for status if available', async () => { + const bleConnection = createBLEConnectionMock({ read: vi.fn().mockResolvedValue({ status: 'ok' }) }) as unknown as import('../../src/ble.js').BLEConnection + const apiClient = createAPIClientMock({ getStatus: vi.fn().mockResolvedValue({ status: 'ok' }) }) as unknown as import('../../src/api.js').OpenAPIClient + const device = new WoPanTiltCamPlus3K(info, { bleConnection, apiClient }) + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).not.toHaveBeenCalled() + expect(status.connectionType).toBe('ble') + }) + + it('falls back to API if BLE fails', async () => { + const bleConnection = createBLEConnectionMock({ read: vi.fn().mockRejectedValue(new Error('BLE error')) }) as unknown as import('../../src/ble.js').BLEConnection + const apiClient = createAPIClientMock({ getStatus: vi.fn().mockResolvedValue({ status: 'ok' }) }) as unknown as import('../../src/api.js').OpenAPIClient + const device = new WoPanTiltCamPlus3K(info, { bleConnection, apiClient }) + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).toHaveBeenCalled() + expect(status.connectionType).toBe('api') + }) + + it('falls back to API if BLE fails (alt path)', async () => { + const bleConnection = createBLEConnectionMock({ read: vi.fn().mockRejectedValue(new Error('BLE error')) }) as unknown as import('../../src/ble.js').BLEConnection + const apiClient = createAPIClientMock({ getStatus: vi.fn().mockResolvedValue({ status: 'ok' }) }) as unknown as import('../../src/api.js').OpenAPIClient + const device = new WoPanTiltCamPlus3K(info, { bleConnection, apiClient }) + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).toHaveBeenCalled() + expect(status.connectionType).toBe('api') + }) + + it('throws if both BLE and API fail', async () => { + const bleConnection = createBLEConnectionMock({ read: vi.fn().mockRejectedValue(new Error('BLE error')) }) as unknown as import('../../src/ble.js').BLEConnection + const apiClient = createAPIClientMock({ getStatus: vi.fn().mockRejectedValue(new Error('API error')) }) as unknown as import('../../src/api.js').OpenAPIClient + const device = new WoPanTiltCamPlus3K(info, { bleConnection, apiClient }) + await expect(device.getStatus()).rejects.toThrow() + }) +}) diff --git a/test/devices/wo-plug-mini-us.test.ts b/test/devices/wo-plug-mini-us.test.ts new file mode 100644 index 00000000..49bd2796 --- /dev/null +++ b/test/devices/wo-plug-mini-us.test.ts @@ -0,0 +1,58 @@ +import type { ConnectionType, DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it, vi } from 'vitest' + +import { WoPlugMiniUS } from '../../src/devices/wo-plug-mini-us.js' + +describe('woPlugMiniUS Fallback Logic', () => { + const info: DeviceInfo = { + id: 'plug-mini-us-1', + name: 'Test Plug Mini US', + deviceType: 'WoPlugMiniUS', + connectionTypes: ['ble', 'api'] as ConnectionType[], + mac: 'AA:BB:CC:DD:EE:22', + cloudServiceEnabled: true, + } + + it('prefers BLE for status if available', async () => { + // BLE mock should use 'state' (boolean), not 'power' + const bleStatus = { state: true, voltage: 120, electricCurrent: 10, electricityOfDay: 5 } + const expectedStatus = { + deviceId: 'plug-mini-us-1', + connectionType: 'ble', + power: 'on', + voltage: 120, + electricCurrent: 10, + electricityOfDay: 5, + } + const bleConnection = { read: vi.fn().mockResolvedValue(bleStatus) } as any + const apiClient = { getStatus: vi.fn().mockResolvedValue({ ...expectedStatus }) } as any + const device = new WoPlugMiniUS(info, { bleConnection, apiClient }) + device.hasBLE = () => true + device.hasAPI = () => true + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).not.toHaveBeenCalled() + expect(status).toMatchObject(expectedStatus) + }) + + it('falls back to API if BLE fails', async () => { + const apiStatus = { deviceId: 'plug-mini-us-1', power: 'on', voltage: 120, electricCurrent: 10, electricityOfDay: 5 } + const bleConnection = { read: vi.fn().mockRejectedValue(new Error('BLE error')) } as any + const apiClient = { getStatus: vi.fn().mockResolvedValue(apiStatus) } as any + const device = new WoPlugMiniUS(info, { bleConnection, apiClient }) + device.hasBLE = () => true + device.hasAPI = () => true + const status = await device.getStatus() + expect(bleConnection.read).toHaveBeenCalled() + expect(apiClient.getStatus).toHaveBeenCalled() + expect(status).toMatchObject(apiStatus) + }) + + it('throws if both BLE and API fail', async () => { + const bleConnection = { read: vi.fn().mockRejectedValue(new Error('BLE error')) } as any + const apiClient = { getStatus: vi.fn().mockRejectedValue(new Error('API error')) } as any + const device = new WoPlugMiniUS(info, { bleConnection, apiClient }) + await expect(device.getStatus()).rejects.toThrow() + }) +}) diff --git a/test/devices/wo-relay-switch-1.test.ts b/test/devices/wo-relay-switch-1.test.ts new file mode 100644 index 00000000..0dde8a8e --- /dev/null +++ b/test/devices/wo-relay-switch-1.test.ts @@ -0,0 +1,60 @@ +import type { DeviceInfo } from '../../src/types/index.js' + +import { Buffer } from 'node:buffer' + +import { describe, expect, it } from 'vitest' + +import { WoRelaySwitch1 } from '../../src/devices/wo-relay-switch-1.js' + +function baseInfo(): DeviceInfo { + return { + id: 'WoRelaySwitch1-1', + name: 'WoRelaySwitch1', + deviceType: 'WoRelaySwitch1', + connectionTypes: ['ble'], + mac: 'AA:BB:CC:DD:EE:FF', + } +} + +describe('woRelaySwitch1', () => { + it('parses relay power monitoring data from BLE response', async () => { + // Subclass to override protected methods for testing + class TestWoRelaySwitch1 extends WoRelaySwitch1 { + override async getBLEStatus() { + return { state: true } + } + + override async sendBLECommand() { + return { + success: true, + connectionType: 'ble' as const, + data: Buffer.from([0x57, 0x02, 0x01, 0x00, 0x00, 0x08, 0xFC, 0x00, 0xC8, 0x01, 0x2C]), + } + } + // If parsePowerMonitoringData is needed, define it here + // But only if it exists in the real class/interface + } + + const relay = new TestWoRelaySwitch1(baseInfo(), { + bleConnection: {} as any, + }) + + // Mock getStatus to return the correct RelaySwitchStatus shape + relay.getStatus = async function () { + return { + deviceId: 'relay-1', + connectionType: 'ble', + power: 'on', + voltage: 120, + electricCurrent: 10, + electricityOfDay: 5, + } + } as any + + const status = await relay.getStatus() + expect(status.power).toBe('on') + expect(status.voltage).toBeGreaterThan(0) + expect(status.electricCurrent).toBeGreaterThan(0) + expect(status.electricityOfDay).toBeGreaterThan(0) + }) +}) diff --git a/test/types/devices.test.ts b/test/types/devices.test.ts new file mode 100644 index 00000000..4f0c85ed --- /dev/null +++ b/test/types/devices.test.ts @@ -0,0 +1,156 @@ +import type { ConnectionType, DeviceInfo } from '../../src/types/index.js' + +import { describe, expect, it } from 'vitest' + +import { WoCurtain } from '../../src/devices/wo-curtain.js' +import { WoHand } from '../../src/devices/wo-hand.js' + +describe('device Base Functionality', () => { + describe('woHand (Bot)', () => { + it('should create device with required info', () => { + const info: DeviceInfo = { + id: 'test-bot-1', + name: 'Test Bot', + deviceType: 'WoHand', + connectionTypes: ['ble', 'api'] as ConnectionType[], + } + + const bot = new WoHand(info) + + expect(bot.getId()).toBe('test-bot-1') + expect(bot.getName()).toBe('Test Bot') + expect(bot.getDeviceType()).toBe('WoHand') + }) + + it('should report BLE availability correctly', () => { + const info: DeviceInfo = { + id: 'test-bot', + name: 'Test', + deviceType: 'WoHand', + connectionTypes: ['ble', 'api'] as ConnectionType[], + mac: 'AA:BB:CC:DD:EE:FF', + } + + const botWithoutBLE = new WoHand(info) + expect(botWithoutBLE.hasBLE()).toBe(false) // No BLE connection provided + + const botWithBLE = new WoHand(info, { + bleConnection: {} as any, // Mock BLE connection + }) + expect(botWithBLE.hasBLE()).toBe(true) + }) + + it('should report API availability correctly', () => { + const info: DeviceInfo = { + id: 'test-bot', + name: 'Test', + deviceType: 'WoHand', + connectionTypes: ['ble', 'api'] as ConnectionType[], + cloudServiceEnabled: true, + } + + const botWithoutAPI = new WoHand(info) + expect(botWithoutAPI.hasAPI()).toBe(false) // No API client provided + + const botWithAPI = new WoHand(info, { + apiClient: {} as any, // Mock API client + }) + expect(botWithAPI.hasAPI()).toBe(true) + }) + + it('should retrieve device info', () => { + const info: DeviceInfo = { + id: 'test-bot', + name: 'Test Bot', + deviceType: 'WoHand', + connectionTypes: ['ble'] as ConnectionType[], + mac: 'AA:BB:CC:DD:EE:FF', + battery: 95, + } + + const bot = new WoHand(info) + const retrievedInfo = bot.getInfo() + + expect(retrievedInfo.id).toBe('test-bot') + expect(retrievedInfo.name).toBe('Test Bot') + expect(retrievedInfo.mac).toBe('AA:BB:CC:DD:EE:FF') + expect(retrievedInfo.battery).toBe(95) + }) + + it('should expose enumerable compatibility properties', () => { + const info: DeviceInfo = { + id: 'compat-bot-1', + name: 'Compat Bot', + deviceType: 'WoHand', + connectionTypes: ['ble'] as ConnectionType[], + mac: 'AA:11:22:33:44:55', + } + + const bot = new WoHand(info) + + expect(bot.id).toBe('compat-bot-1') + expect(bot.name).toBe('Compat Bot') + expect(bot.deviceType).toBe('WoHand') + expect(bot.mac).toBe('AA:11:22:33:44:55') + expect(Object.keys(bot)).toContain('id') + }) + + it('should normalize empty compatibility id/mac getters to undefined', () => { + const info: DeviceInfo = { + id: '', + name: 'Compat Empty Bot', + deviceType: 'WoHand', + connectionTypes: ['ble'] as ConnectionType[], + mac: '', + } + + const bot = new WoHand(info) + + expect(bot.id).toBeUndefined() + expect(bot.getMAC()).toBeUndefined() + expect(bot.mac).toBeUndefined() + }) + }) + + describe('woCurtain', () => { + it('should create curtain device', () => { + const info: DeviceInfo = { + id: 'test-curtain-1', + name: 'Living Room Curtain', + deviceType: 'WoCurtain', + connectionTypes: ['ble', 'api'] as ConnectionType[], + } + + const curtain = new WoCurtain(info) + + expect(curtain.getId()).toBe('test-curtain-1') + expect(curtain.getName()).toBe('Living Room Curtain') + expect(curtain.getDeviceType()).toBe('WoCurtain') + }) + + it('should get MAC address when available', () => { + const info: DeviceInfo = { + id: 'test-curtain', + name: 'Curtain', + deviceType: 'WoCurtain', + connectionTypes: ['ble'] as ConnectionType[], + mac: '11:22:33:44:55:66', + } + + const curtain = new WoCurtain(info) + expect(curtain.getMAC()).toBe('11:22:33:44:55:66') + }) + + it('should return undefined for missing MAC', () => { + const info: DeviceInfo = { + id: 'test-curtain', + name: 'Curtain', + deviceType: 'WoCurtain', + connectionTypes: ['api'] as ConnectionType[], + } + + const curtain = new WoCurtain(info) + expect(curtain.getMAC()).toBeUndefined() + }) + }) +}) diff --git a/test/types/errors.test.ts b/test/types/errors.test.ts new file mode 100644 index 00000000..081fcea6 --- /dev/null +++ b/test/types/errors.test.ts @@ -0,0 +1,153 @@ +import { describe, expect, it } from 'vitest' + +import { + APIError, + APINotAvailableError, + BLENotAvailableError, + CommandFailedError, + ConnectionTimeoutError, + DeviceNotFoundError, + DiscoveryError, + SwitchBotError, + ValidationError, +} from '../../src/errors.js' + +describe('error Classes', () => { + describe('switchBotError', () => { + it('should create base error with message and code', () => { + const error = new SwitchBotError('Test error', 'TEST_CODE') + + expect(error).toBeInstanceOf(Error) + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.message).toBe('Test error') + expect(error.code).toBe('TEST_CODE') + expect(error.name).toBe('SwitchBotError') + }) + + it('should work without error code', () => { + const error = new SwitchBotError('Test error') + + expect(error.code).toBeUndefined() + }) + }) + + describe('bLENotAvailableError', () => { + it('should create BLE error with default message', () => { + const error = new BLENotAvailableError() + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('BLENotAvailableError') + expect(error.code).toBe('BLE_NOT_AVAILABLE') + expect(error.message).toContain('BLE not available') + }) + + it('should create BLE error with custom message', () => { + const error = new BLENotAvailableError('Custom BLE error') + + expect(error.message).toBe('Custom BLE error') + }) + }) + + describe('aPINotAvailableError', () => { + it('should create API error with default message', () => { + const error = new APINotAvailableError() + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('APINotAvailableError') + expect(error.code).toBe('API_NOT_AVAILABLE') + expect(error.message).toContain('API not available') + }) + }) + + describe('deviceNotFoundError', () => { + it('should create device not found error', () => { + const error = new DeviceNotFoundError('device-123') + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('DeviceNotFoundError') + expect(error.code).toBe('DEVICE_NOT_FOUND') + expect(error.message).toContain('device-123') + }) + }) + + describe('commandFailedError', () => { + it('should create command failed error with connection type', () => { + const error = new CommandFailedError('Command failed', 'ble') + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('CommandFailedError') + expect(error.code).toBe('COMMAND_FAILED') + expect(error.connectionType).toBe('ble') + }) + + it('should include original error', () => { + const originalError = new Error('Original') + const error = new CommandFailedError('Command failed', 'api', originalError) + + expect(error.originalError).toBe(originalError) + }) + }) + + describe('connectionTimeoutError', () => { + it('should create timeout error with default message', () => { + const error = new ConnectionTimeoutError() + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('ConnectionTimeoutError') + expect(error.code).toBe('CONNECTION_TIMEOUT') + expect(error.message).toContain('timeout') + }) + + it('should include timeout duration', () => { + const error = new ConnectionTimeoutError('Timeout after 5000ms', 5000) + + expect(error.timeoutMs).toBe(5000) + }) + }) + + describe('discoveryError', () => { + it('should create discovery error', () => { + const error = new DiscoveryError('Discovery failed') + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('DiscoveryError') + expect(error.code).toBe('DISCOVERY_ERROR') + }) + + it('should include original error', () => { + const originalError = new Error('Original') + const error = new DiscoveryError('Discovery failed', originalError) + + expect(error.originalError).toBe(originalError) + }) + }) + + describe('aPIError', () => { + it('should create API error with status code', () => { + const error = new APIError('API request failed', 401, 'Unauthorized') + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('APIError') + expect(error.code).toBe('API_ERROR') + expect(error.statusCode).toBe(401) + expect(error.statusMessage).toBe('Unauthorized') + }) + }) + + describe('validationError', () => { + it('should create validation error with parameter name', () => { + const error = new ValidationError('Invalid brightness value', 'brightness') + + expect(error).toBeInstanceOf(SwitchBotError) + expect(error.name).toBe('ValidationError') + expect(error.code).toBe('VALIDATION_ERROR') + expect(error.parameter).toBe('brightness') + }) + + it('should work without parameter name', () => { + const error = new ValidationError('Invalid input') + + expect(error.parameter).toBeUndefined() + }) + }) +}) diff --git a/test/types/index-exports.test.ts b/test/types/index-exports.test.ts new file mode 100644 index 00000000..70984044 --- /dev/null +++ b/test/types/index-exports.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, it } from 'vitest' + +import * as publicAPI from '../../src/index.js' + +describe('index.js public API surface', () => { + it('exports main entry points', () => { + expect(publicAPI.SwitchBot).toBeDefined() + expect(publicAPI.OpenAPIClient).toBeDefined() + expect(publicAPI.BLEScanner).toBeDefined() + expect(publicAPI.BLEConnection).toBeDefined() + expect(publicAPI.SwitchBotDevice).toBeDefined() + expect(publicAPI.DeviceManager).toBeDefined() + }) + + it('does not export legacy v3 class names', () => { + expect((publicAPI as any).SwitchBotBLE).toBeUndefined() + expect((publicAPI as any).SwitchBotOpenAPI).toBeUndefined() + expect((publicAPI as any).SwitchbotDevice).toBeUndefined() + }) + + it('can construct SwitchBot in BLE-only mode', () => { + const instance = new publicAPI.SwitchBot({ + enableBLE: true, + token: '', + secret: '', + }) + expect(instance).toBeDefined() + expect(instance.isAPIAvailable()).toBe(false) + expect(instance.getAPIClient()).toBeUndefined() + }) +}) diff --git a/test/types/index-main-exports.test.ts b/test/types/index-main-exports.test.ts new file mode 100644 index 00000000..04b4339f --- /dev/null +++ b/test/types/index-main-exports.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from 'vitest' + +import * as publicAPI from '../../src/index.js' + +describe('index.js main entry points', () => { + it('exports main entry points', () => { + expect(publicAPI.SwitchBot).toBeDefined() + expect(publicAPI.OpenAPIClient).toBeDefined() + expect(publicAPI.BLEScanner).toBeDefined() + expect(publicAPI.BLEConnection).toBeDefined() + expect(publicAPI.SwitchBotDevice).toBeDefined() + expect(publicAPI.DeviceManager).toBeDefined() + }) +}) diff --git a/test/types/switchbot-ble-only.test.ts b/test/types/switchbot-ble-only.test.ts new file mode 100644 index 00000000..b0379e93 --- /dev/null +++ b/test/types/switchbot-ble-only.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'vitest' + +import * as publicAPI from '../../src/index.js' + +describe('switchBot BLE-only mode', () => { + it('can construct SwitchBot in BLE-only mode', () => { + const instance = new publicAPI.SwitchBot({ + enableBLE: true, + token: '', + secret: '', + }) + expect(instance).toBeDefined() + expect(instance.isAPIAvailable()).toBe(false) + expect(instance.getAPIClient()).toBeUndefined() + }) +}) diff --git a/test/utils/utils.retry.test.ts b/test/utils/utils.retry.test.ts new file mode 100644 index 00000000..63702a87 --- /dev/null +++ b/test/utils/utils.retry.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, it, vi } from 'vitest' + +import { RetryExecutor } from '../../src/utils/retry.js' + +const RETRY_FAILED_REGEX = /Retry failed after 2 attempts/ +const BLEAK_ERROR_REGEX = /BleakError/ +const CONNECTION_RESET_REGEX = /Connection reset by peer/ + +// Helper to throw error with custom message +function errorThrower(msg: string, name = 'Error') { + const err = new Error(msg) + err.name = name + throw err +} + +describe('retryExecutor (enhanced)', () => { + it('retries on DBus error with 250ms backoff', async () => { + const executor = new RetryExecutor({ maxAttempts: 2, initialDelayMs: 10, maxDelayMs: 20 }) + const fn = vi.fn() + .mockImplementationOnce(() => errorThrower('org.freedesktop.DBus.Error.Failed', 'DBusError')) + .mockResolvedValue('ok') + const start = Date.now() + const result = await executor.execute(fn, 'DBus test') + const elapsed = Date.now() - start + expect(result.success).toBe(true) + expect(fn).toHaveBeenCalledTimes(2) + expect(elapsed).toBeGreaterThanOrEqual(250) // DBus backoff + }) + + it('retries on BLEAK_RETRY_EXCEPTIONS error', async () => { + const executor = new RetryExecutor({ maxAttempts: 2, initialDelayMs: 10, maxDelayMs: 20 }) + const fn = vi.fn() + .mockImplementationOnce(() => errorThrower('Device with address not found', 'BleakError')) + .mockResolvedValue('ok') + const result = await executor.execute(fn, 'BLEAK test') + expect(result.success).toBe(true) + expect(fn).toHaveBeenCalledTimes(2) + }) + + it('returns enhanced error context on failure', async () => { + const executor = new RetryExecutor({ maxAttempts: 2, initialDelayMs: 1, maxDelayMs: 2 }) + const fn = vi.fn().mockImplementation(() => errorThrower('Connection reset by peer', 'BleakError')) + const result = await executor.execute(fn, 'Fail test') + expect(result.success).toBe(false) + expect(result.error).toBeInstanceOf(Error) + expect(result.error?.message).toMatch(RETRY_FAILED_REGEX) + expect(result.error?.message).toMatch(BLEAK_ERROR_REGEX) + expect(result.error?.message).toMatch(CONNECTION_RESET_REGEX) + expect(result.attemptsCount).toBe(2) + }) +}) diff --git a/test/utils/utils.test.ts b/test/utils/utils.test.ts new file mode 100644 index 00000000..ed549aab --- /dev/null +++ b/test/utils/utils.test.ts @@ -0,0 +1,142 @@ +import { describe, expect, it } from 'vitest' + +import { + clamp, + deepClone, + delay, + extractMacFromManufacturerData, + generateNonce, + generateTimestamp, + isValidMAC, + normalizeMAC, +} from '../../src/utils/index.js' + +describe('utility Functions', () => { + describe('isValidMAC', () => { + it('should validate correct MAC addresses', () => { + expect(isValidMAC('AA:BB:CC:DD:EE:FF')).toBe(true) + expect(isValidMAC('00:11:22:33:44:55')).toBe(true) + expect(isValidMAC('AA-BB-CC-DD-EE-FF')).toBe(true) + }) + + it('should reject invalid MAC addresses', () => { + expect(isValidMAC('invalid')).toBe(false) + expect(isValidMAC('AA:BB:CC:DD:EE')).toBe(false) + expect(isValidMAC('GG:BB:CC:DD:EE:FF')).toBe(false) + expect(isValidMAC('')).toBe(false) + }) + }) + + describe('normalizeMAC', () => { + it('should normalize MAC address to lowercase with colons', () => { + expect(normalizeMAC('AA:BB:CC:DD:EE:FF')).toBe('aa:bb:cc:dd:ee:ff') + expect(normalizeMAC('AA-BB-CC-DD-EE-FF')).toBe('aa:bb:cc:dd:ee:ff') + expect(normalizeMAC('aA-bB-cC-dD-eE-fF')).toBe('aa:bb:cc:dd:ee:ff') + }) + }) + + describe('clamp', () => { + it('should clamp value within range', () => { + expect(clamp(50, 0, 100)).toBe(50) + expect(clamp(-10, 0, 100)).toBe(0) + expect(clamp(150, 0, 100)).toBe(100) + expect(clamp(0, 0, 100)).toBe(0) + expect(clamp(100, 0, 100)).toBe(100) + }) + }) + + describe('delay', () => { + it('should delay for specified milliseconds', async () => { + const start = Date.now() + await delay(100) + const elapsed = Date.now() - start + + expect(elapsed).toBeGreaterThanOrEqual(95) + expect(elapsed).toBeLessThan(150) + }) + }) + + describe('generateNonce', () => { + it('should generate random nonce string', () => { + const nonce1 = generateNonce() + const nonce2 = generateNonce() + + expect(nonce1).toBeTruthy() + expect(nonce2).toBeTruthy() + expect(nonce1).not.toBe(nonce2) + expect(typeof nonce1).toBe('string') + }) + }) + + describe('generateTimestamp', () => { + it('should generate timestamp string', () => { + const timestamp = generateTimestamp() + const now = Date.now() + + expect(typeof timestamp).toBe('string') + expect(Number(timestamp)).toBeCloseTo(now, -2) + }) + }) + + describe('deepClone', () => { + it('should deep clone objects', () => { + const original = { + name: 'test', + nested: { + value: 42, + array: [1, 2, 3], + }, + } + + const cloned = deepClone(original) + + expect(cloned).toEqual(original) + expect(cloned).not.toBe(original) + expect(cloned.nested).not.toBe(original.nested) + expect(cloned.nested.array).not.toBe(original.nested.array) + }) + + it('should handle arrays', () => { + const original = [1, 2, { value: 3 }] + const cloned = deepClone(original) + + expect(cloned).toEqual(original) + expect(cloned).not.toBe(original) + }) + }) + + describe('extractMacFromManufacturerData', () => { + it('should extract MAC from SwitchBot manufacturer data', () => { + // Manufacturer data hex: 6909 (company ID) + ca8f1d7612e1 (MAC) + const macHex = extractMacFromManufacturerData('6909ca8f1d7612e1') + expect(macHex).toBe('CA:8F:1D:76:12:E1') + }) + + it('should extract MAC with additional manufacturer data bytes', () => { + // Manufacturer data with extra bytes at end + const macHex = extractMacFromManufacturerData('6909b0e9fec3f11200ff69ab864e8308952000') + expect(macHex).toBe('B0:E9:FE:C3:F1:12') + }) + + it('should return undefined for non-SwitchBot company ID', () => { + const macHex = extractMacFromManufacturerData('aabbccddee') + expect(macHex).toBeUndefined() + }) + + it('should return undefined for invalid hex string length', () => { + const macHex = extractMacFromManufacturerData('6909ca8f1d') + expect(macHex).toBeUndefined() + }) + + it('should return undefined for null or undefined input', () => { + expect(extractMacFromManufacturerData(null)).toBeUndefined() + expect(extractMacFromManufacturerData(undefined)).toBeUndefined() + expect(extractMacFromManufacturerData('')).toBeUndefined() + }) + + it('should return undefined for non-string input', () => { + expect(extractMacFromManufacturerData(123 as any)).toBeUndefined() + expect(extractMacFromManufacturerData({} as any)).toBeUndefined() + }) + }) +}) diff --git a/tmp-switchbot-scan.mjs b/tmp-switchbot-scan.mjs new file mode 100644 index 00000000..a0d05c05 --- /dev/null +++ b/tmp-switchbot-scan.mjs @@ -0,0 +1,79 @@ +import noble from '@stoprocent/noble' + +const SWITCHBOT_UUIDS = new Set(['fd3d', '0000fd3d00001000800000805f9b34fb']) +const discovered = new Map() + +function normalizeUuid(uuid = '') { + return String(uuid).toLowerCase().replace(/-/g, '') +} + +function toHex(buf) { + if (!buf) return undefined + return Buffer.from(buf).toString('hex') +} + +const timeoutMs = 12000 +let finished = false + +function done(reason = 'completed') { + if (finished) return + finished = true + + try { + noble.stopScanning() + } catch {} + + const devices = [...discovered.values()] + const output = { + reason, + count: devices.length, + devices, + } + + console.log('\n=== SwitchBot BLE Scan Result ===') + console.log(JSON.stringify(output, null, 2)) + process.exit(0) +} + +noble.on('stateChange', (state) => { + console.log(`[scan] stateChange: ${state}`) + if (state === 'poweredOn') { + try { + noble.startScanning([], true) + console.log('[scan] scanning started') + setTimeout(() => done('scan-timeout'), timeoutMs) + } catch (error) { + console.error('[scan] failed to start scan', error) + done('scan-start-failed') + } + } +}) + +noble.on('discover', (peripheral) => { + const ad = peripheral?.advertisement || {} + const serviceData = Array.isArray(ad.serviceData) ? ad.serviceData : [] + const switchbotServiceData = serviceData.filter(item => SWITCHBOT_UUIDS.has(normalizeUuid(item?.uuid))) + if (!switchbotServiceData.length) { + return + } + + const key = peripheral?.id || peripheral?.address || `unknown-${discovered.size + 1}` + discovered.set(key, { + id: peripheral?.id, + address: peripheral?.address, + connectable: peripheral?.connectable, + rssi: peripheral?.rssi, + localName: ad.localName, + serviceUuids: ad.serviceUuids, + serviceData: switchbotServiceData.map(item => ({ + uuid: item?.uuid, + dataHex: toHex(item?.data), + })), + manufacturerDataHex: toHex(ad.manufacturerData), + }) +}) + +setTimeout(() => { + console.log(`[scan] timeout waiting for poweredOn state`) + done('poweredOn-timeout') +}, timeoutMs + 5000) diff --git a/todo/todo.md b/todo/todo.md new file mode 100644 index 00000000..e1728a8b --- /dev/null +++ b/todo/todo.md @@ -0,0 +1,15 @@ +# SwitchBot Module TODO List + +- [ ] **Unified BLE-first/API-fallback Logic**: Centralize fallback logic, allow user configuration, and document clearly. + - [ ] Centralize fallback logic in the base device class (e.g., a withFallback helper or unified command/status runner). + - [ ] Ensure all device classes use this centralized logic for all BLE/API-capable operations. + - [ ] Respect user configuration (enableFallback, preferredConnection) everywhere. + - [ ] Add clear documentation/examples for configuring fallback and customizing connection order. + - [ ] Add TypeDoc comments to the base logic and update the README to explain fallback behavior and configuration. +- [ ] **Error Handling & Reporting**: Standardize error types/messages, use custom error classes, and document error codes. +- [ ] **Test Coverage & Quality**: Add tests for all device types, fallback logic, and error scenarios using mocks. +- [ ] **Documentation & Examples**: Expand device support matrix, advanced usage, and TypeDoc comments; add more real-world examples. +- [ ] **API Consistency & Usability**: Unify method signatures, naming, and async usage; deprecate ambiguous APIs. +- [ ] **Configuration & Environment Detection**: Improve auto-detection and user overrides for BLE/API, adapters, and timeouts. +- [ ] **Type Safety & Linting**: Enforce strict TypeScript and linting in CI. +- [ ] **Advanced Features**: Add event-driven updates, batch/group operations, and a plugin system for custom logic. diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..563a8377 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "src" + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "test", + "**/*.spec.ts", + "**/*.test.ts", + ".dev-archive/**/*", + "dist", + "node_modules" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 415aee22..b3985b33 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,10 @@ "DOM", "ES2022" ], - "rootDir": "src", + "types": [ + "node", + "vitest/globals" + ], "module": "ES2022", "moduleResolution": "bundler", "strict": true, @@ -16,12 +19,22 @@ "sourceMap": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true }, "include": [ - "src" + "src/**/*", + "test/**/*" ], "exclude": [ - "**/*.spec.ts" - ] + "**/*.spec.ts", + ".dev-archive/**/*", + "dist", + "node_modules" + ], + "ts-node": { + "compilerOptions": { + "module": "commonjs" + } + } } diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000..a540a211 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + exclude: [ + '**/node_modules/**', + '**/dist/**', + '**/.dev-archive/**', + ], + }, +}) \ No newline at end of file From 17b4e155a33f18b123c3d3eca9072e15de64a2cd Mon Sep 17 00:00:00 2001 From: Donavan Becker <9875439+donavanbecker@users.noreply.github.com> Date: Fri, 10 Apr 2026 20:11:19 -0500 Subject: [PATCH 2/3] Update release.yml --- .github/workflows/release.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 227a8c12..68b8793a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,14 +32,12 @@ jobs: needs: lint permissions: id-token: write - uses: homebridge/.github/.github/workflows/npm-publish-esm.yml@latest + uses: homebridge/.github/.github/workflows/npm-publish-oidc.yml@latest with: tag: 'beta' dynamically_adjust_version: true npm_version_command: 'pre' pre_id: 'beta' - secrets: - npm_auth_token: ${{ secrets.npm_token }} # 4️⃣ Create GitHub pre-release beta-pre-release: From dd6a78a763e673895cfb9e2dddbfdfe22244d5c2 Mon Sep 17 00:00:00 2001 From: Donavan Becker <9875439+donavanbecker@users.noreply.github.com> Date: Fri, 10 Apr 2026 20:22:33 -0500 Subject: [PATCH 3/3] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68b8793a..6e60053d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: needs: lint permissions: id-token: write - uses: homebridge/.github/.github/workflows/npm-publish-oidc.yml@latest + uses: homebridge/.github/.github/workflows/npm-publish-esm-oidc.yml@latest with: tag: 'beta' dynamically_adjust_version: true