UNPKG

homebridge-hatch-baby-rest-volume

Version:
133 lines (132 loc) 4.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HatchBabyRestPlus = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const util_1 = require("./util"); const rgb2hsv = require('pure-color/convert/rgb2hsv'), hsv2rgb = require('pure-color/convert/hsv2rgb'); const MAX_VALUE = 65535; function convertFromPercentage(percentage) { return Math.floor((percentage / 100) * MAX_VALUE); } function convertToPercentage(value) { return Math.floor((value * 100) / MAX_VALUE); } function convertToHexRange(value) { return Math.floor((value / MAX_VALUE) * 255); } function convertFromHexRange(value) { return Math.floor((value * MAX_VALUE) / 255); } function colorToHsb({ r, g, b }) { const [h, s, v] = rgb2hsv([r, g, b].map(convertToHexRange)); return { h, s, b: v }; } function assignState(previousState, changes) { const state = Object.assign({}, previousState); for (const key in changes) { if (typeof changes[key] === 'object') { state[key] = Object.assign(previousState[key] || {}, changes[key]); } else { state[key] = changes[key]; } } return state; } class HatchBabyRestPlus { constructor(info) { this.info = info; this.onCurrentState = new rxjs_1.BehaviorSubject(null); this.onState = this.onCurrentState.pipe(operators_1.filter((state) => state !== null)); this.onAudioOn = this.onState.pipe(operators_1.map((state) => state.a.t > 0), operators_1.distinctUntilChanged()); this.onVolume = this.onState.pipe(operators_1.map((state) => convertToPercentage(state.a.v)), operators_1.distinctUntilChanged()); this.onAudioTrack = this.onState.pipe(operators_1.map((state) => state.a.t), operators_1.distinctUntilChanged()); this.onIsPowered = this.onState.pipe(operators_1.map((state) => state.isPowered), operators_1.distinctUntilChanged()); this.onBrightness = this.onState.pipe(operators_1.map((state) => convertToPercentage(state.c.i)), operators_1.distinctUntilChanged()); this.onHsb = this.onState.pipe(operators_1.map((state) => colorToHsb(state.c))); this.onHue = this.onHsb.pipe(operators_1.map(({ h }) => h), operators_1.distinctUntilChanged()); this.onSaturation = this.onHsb.pipe(operators_1.map(({ s }) => s), operators_1.distinctUntilChanged()); this.onBatteryLevel = this.onState.pipe(operators_1.map((state) => state.deviceInfo.b), operators_1.distinctUntilChanged()); } get id() { return this.info.id; } get name() { return this.info.name; } registerMqttClient(mqttClient) { const { thingName } = this.info; let getClientToken; this.mqttClient = mqttClient; mqttClient.on('status', (topic, message, clientToken, status) => { if (clientToken !== getClientToken) { return; } const { state } = status; this.onCurrentState.next(assignState(state.reported, state.desired)); }); mqttClient.on('foreignStateChange', (topic, message, s) => { const currentState = this.onCurrentState.getValue(); if (!currentState) { return; } this.onCurrentState.next(assignState(assignState(currentState, s.state.reported), s.state.desired)); }); mqttClient.on('connect', () => { mqttClient.register(thingName, {}, () => { getClientToken = mqttClient.get(thingName); }); }); } getCurrentState() { return this.onState.pipe(operators_1.take(1)).toPromise(); } update(update) { if (!this.mqttClient) { util_1.logError(`Unable to Update ${this.name} - No MQTT Client Registered`); return; } this.mqttClient.update(this.info.thingName, { state: { desired: update, }, }); } setVolume(percentage) { this.update({ a: { v: convertFromPercentage(percentage), }, }); } setAudioTrack(audioTrack) { this.update({ a: { t: audioTrack, }, }); } setColor(color) { this.update({ c: color, }); } setColorFromHueAndSaturation(hue, saturation) { const [r, g, b] = hsv2rgb([hue, saturation, 100]).map(convertFromHexRange); this.setColor({ r, g, b, R: false, W: false }); } setBrightness(percentage) { this.update({ c: { i: convertFromPercentage(percentage), }, }); } setPower(on) { this.update({ isPowered: on, }); } } exports.HatchBabyRestPlus = HatchBabyRestPlus;