UNPKG

node-switchbot

Version:

The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE) with automatic OpenAPI fallback.

168 lines 6.06 kB
/* 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 { /** * Open blind (position 50%) */ async open() { // 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() { // 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() { // 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() { // 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() { // 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) { // 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]; 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'); } _lastPosition; async getStatus() { return this.getStatusWithFallback((bleData) => { let direction; const position = typeof bleData.position === 'number' ? bleData.position : 0; let calibrated; 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; 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(), }; }); } } //# sourceMappingURL=wo-blind-tilt.js.map