UNPKG

homebridge-sleeptracker

Version:

Homebridge plugin for SleepTracker smart beds - Control your bed's position and features through HomeKit

292 lines 12.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SleepTrackerAccessory = void 0; const client_1 = require("./api/client"); const types_1 = require("./api/types"); class SleepTrackerAccessory { constructor(platform, accessory) { this.platform = platform; this.accessory = accessory; this.isInitialized = false; this.lastKnownState = { temperature: null, humidity: null, }; this.MAX_RETRIES = 3; this.RETRY_DELAY = 1000; // 1초 this.client = new client_1.SleepTrackerClient(this.platform.config.username, this.platform.config.password, this.platform.config.deviceId); this.accessory.getService(this.platform.Service.AccessoryInformation) .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SleepTracker') .setCharacteristic(this.platform.Characteristic.Model, 'Smart Bed') .setCharacteristic(this.platform.Characteristic.SerialNumber, this.platform.config.deviceId); // Head Up switch this.headUpService = this.accessory.getService('Head Up') || this.accessory.addService(this.platform.Service.Switch, 'Head Up', 'head-up'); this.headUpService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setHeadUp.bind(this)) .onGet(this.getHeadUp.bind(this)); // Head Down switch this.headDownService = this.accessory.getService('Head Down') || this.accessory.addService(this.platform.Service.Switch, 'Head Down', 'head-down'); this.headDownService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setHeadDown.bind(this)) .onGet(this.getHeadDown.bind(this)); // Foot Up switch this.footUpService = this.accessory.getService('Foot Up') || this.accessory.addService(this.platform.Service.Switch, 'Foot Up', 'foot-up'); this.footUpService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setFootUp.bind(this)) .onGet(this.getFootUp.bind(this)); // Foot Down switch this.footDownService = this.accessory.getService('Foot Down') || this.accessory.addService(this.platform.Service.Switch, 'Foot Down', 'foot-down'); this.footDownService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setFootDown.bind(this)) .onGet(this.getFootDown.bind(this)); // Preset services this.flatPresetService = this.accessory.getService('Flat Position') || this.accessory.addService(this.platform.Service.Switch, 'Flat Position', 'flat-preset'); this.flatPresetService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setFlatPreset.bind(this)) .onGet(this.getPresetState.bind(this)); this.zeroGPresetService = this.accessory.getService('Zero G') || this.accessory.addService(this.platform.Service.Switch, 'Zero G', 'zerog-preset'); this.zeroGPresetService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setZeroGPreset.bind(this)) .onGet(this.getPresetState.bind(this)); this.antiSnorePresetService = this.accessory.getService('Anti Snore') || this.accessory.addService(this.platform.Service.Switch, 'Anti Snore', 'antisnore-preset'); this.antiSnorePresetService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setAntiSnorePreset.bind(this)) .onGet(this.getPresetState.bind(this)); this.tvPresetService = this.accessory.getService('TV Position') || this.accessory.addService(this.platform.Service.Switch, 'TV Position', 'tv-preset'); this.tvPresetService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setTVPreset.bind(this)) .onGet(this.getPresetState.bind(this)); // Initialize device with retries this.initializeDeviceWithRetry(); // Start polling for updates (only for environment sensors) if (this.platform.config.enableEnvironmentSensors) { setInterval(() => this.updateState(), this.platform.config.refreshInterval * 1000 || 30000); } } async initializeDeviceWithRetry(retryCount = 0) { try { await this.initializeDevice(); this.isInitialized = true; } catch (error) { if (retryCount < this.MAX_RETRIES) { this.platform.log.warn(`Failed to initialize device, retrying in ${this.RETRY_DELAY}ms...`); setTimeout(() => this.initializeDeviceWithRetry(retryCount + 1), this.RETRY_DELAY); } else { this.platform.log.error('Failed to initialize device after maximum retries'); } } } async initializeDevice() { const deviceInfo = await this.client.getDeviceInfo(this.platform.config.deviceId); // Setup environment sensors if enabled if (this.platform.config.enableEnvironmentSensors && deviceInfo.productFeatures.includes('env_sensors')) { this.setupEnvironmentSensors(); } } setupEnvironmentSensors() { // Temperature sensor this.temperatureService = this.accessory.getService('Temperature') || this.accessory.addService(this.platform.Service.TemperatureSensor, 'Temperature', 'temperature'); // Humidity sensor this.humidityService = this.accessory.getService('Humidity') || this.accessory.addService(this.platform.Service.HumiditySensor, 'Humidity', 'humidity'); } async updateState() { if (!this.isInitialized || !this.platform.config.enableEnvironmentSensors) { return; } try { // Update environment sensors if available if (this.temperatureService || this.humidityService) { const sensorData = await this.client.getEnvironmentSensorData(this.platform.config.deviceId); if (sensorData.temperature !== null && this.temperatureService) { this.lastKnownState.temperature = sensorData.temperature; this.temperatureService.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, sensorData.temperature); } if (sensorData.humidity !== null && this.humidityService) { this.lastKnownState.humidity = sensorData.humidity; this.humidityService.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, sensorData.humidity); } } } catch (error) { this.platform.log.error('Failed to update environment sensors:', error); } } async sendCommandWithRetry(command, retryCount = 0) { try { await this.client.sendCommand(this.platform.config.deviceId, command); } catch (error) { if (retryCount < this.MAX_RETRIES) { this.platform.log.warn(`Command failed, retrying in ${this.RETRY_DELAY}ms...`); await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY)); return this.sendCommandWithRetry(command, retryCount + 1); } throw error; } } // Head position handlers async setHeadUp(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.HeadUp); } catch (error) { this.platform.log.error('Failed to start head up movement:', error); throw error; } } else { try { await this.sendCommandWithRetry(types_1.Commands.Stop); } catch (error) { this.platform.log.error('Failed to stop movement:', error); throw error; } } } async getHeadUp() { return false; // Always return false to allow toggling } async setHeadDown(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.HeadDown); } catch (error) { this.platform.log.error('Failed to start head down movement:', error); throw error; } } else { try { await this.sendCommandWithRetry(types_1.Commands.Stop); } catch (error) { this.platform.log.error('Failed to stop movement:', error); throw error; } } } async getHeadDown() { return false; // Always return false to allow toggling } // Foot position handlers async setFootUp(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.FootUp); } catch (error) { this.platform.log.error('Failed to start foot up movement:', error); throw error; } } else { try { await this.sendCommandWithRetry(types_1.Commands.Stop); } catch (error) { this.platform.log.error('Failed to stop movement:', error); throw error; } } } async getFootUp() { return false; // Always return false to allow toggling } async setFootDown(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.FootDown); } catch (error) { this.platform.log.error('Failed to start foot down movement:', error); throw error; } } else { try { await this.sendCommandWithRetry(types_1.Commands.Stop); } catch (error) { this.platform.log.error('Failed to stop movement:', error); throw error; } } } async getFootDown() { return false; // Always return false to allow toggling } // Preset handlers async setFlatPreset(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.Flat); this.resetPresetSwitch(this.flatPresetService); } catch (error) { this.platform.log.error('Failed to set Flat preset:', error); throw error; } } } async setZeroGPreset(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.ZeroG); this.resetPresetSwitch(this.zeroGPresetService); } catch (error) { this.platform.log.error('Failed to set Zero G preset:', error); throw error; } } } async setAntiSnorePreset(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.AntiSnore); this.resetPresetSwitch(this.antiSnorePresetService); } catch (error) { this.platform.log.error('Failed to set Anti Snore preset:', error); throw error; } } } async setTVPreset(value) { if (value) { try { await this.sendCommandWithRetry(types_1.Commands.TV); this.resetPresetSwitch(this.tvPresetService); } catch (error) { this.platform.log.error('Failed to set TV preset:', error); throw error; } } } async getPresetState() { return false; } resetPresetSwitch(service) { setTimeout(() => { service.updateCharacteristic(this.platform.Characteristic.On, false); }, 1000); } } exports.SleepTrackerAccessory = SleepTrackerAccessory; //# sourceMappingURL=sleepTrackerAccessory.js.map