UNPKG

@constructorfleet/ultimate-govee

Version:

Library for interacting with Govee devices written in Typescript.

154 lines 7.48 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var GoveeEffectService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoveeEffectService = void 0; const common_1 = require("@nestjs/common"); const moment_1 = __importDefault(require("moment")); const semaphore_async_await_1 = __importDefault(require("semaphore-async-await")); const _ultimate_govee_persist_1 = require("../../../persist"); const utils_1 = require("../../utils"); const govee_effect_config_1 = require("./govee-effect.config"); const effect_list_response_1 = require("./models/effect-list.response"); const scene_list_response_1 = require("./models/scene-list.response"); let GoveeEffectService = GoveeEffectService_1 = class GoveeEffectService { constructor(config) { this.config = config; this.logger = new common_1.Logger(GoveeEffectService_1.name); this.lock = new semaphore_async_await_1.default(1); this.deviceEffectData = {}; } async getEffects(authState, model, goodsType, deviceId) { const oauth = authState?.accountAuth?.oauth; if (!oauth) { return []; } await this.lock.acquire(); const deviceEffectData = this.deviceEffectData[model]; try { if (deviceEffectData !== undefined && deviceEffectData.lastUpdate.add(1, 'hour').isAfter((0, moment_1.default)())) { this.logger.log('Last update within last hour, using previous result.'); return deviceEffectData.effects; } const persisted = await _ultimate_govee_persist_1.PersistModule.getPersistedFile({ filename: `govee.${model}.effects.json`, }); if (persisted.data !== undefined && persisted.lastUpdate !== undefined) { if (persisted.lastUpdate.add(1, 'hour').isAfter((0, moment_1.default)())) { this.deviceEffectData[model] = { lastUpdate: persisted.lastUpdate, effects: persisted.data, }; this.logger.log('Last update within last hour, using previous result.'); return this.deviceEffectData[model].effects; } } const [deviceScenes, deviceEffects] = await Promise.all([ this.getDeviceScenes(oauth, model, goodsType, deviceId), this.getDeviceEffects(oauth, model, goodsType, deviceId), ]); const effects = deviceEffects ?? []; // Add any scene not already defined effects.push(...(deviceScenes ?? []).filter((effect) => effects.find((e) => e.name === effect.name) === undefined)); this.deviceEffectData[model] = { lastUpdate: (0, moment_1.default)(), effects, }; return effects; } catch (error) { this.logger.error('Unable to retrieve device light effects/scenes', error); return deviceEffectData?.effects; } finally { this.lock.release(); } } async getDeviceEffects(oauth, model, goodsType, deviceId) { try { this.logger.log(`Retrieving light effects for device ${model} ${deviceId} from Govee REST API`); const response = await (0, utils_1.request)(this.config.deviceEffectUrl, this.config.headers(oauth), { sku: model, goodsType, device: deviceId, }).get(effect_list_response_1.EffectListResponse); return response.data.effectData.categories.reduce((effects, category) => { category.scenes.forEach((scene) => { effects.push(...scene.lightEffects.map((lightEffect) => { const code = [0, undefined, null].includes(lightEffect.code) ? scene.code : lightEffect.code; return { name: `${scene.name} ${lightEffect.name}`.trim(), code, opCode: lightEffect.specialEffect ?.find((s) => s.supportedModels?.includes(model) === true) ?.opCode(code) ?? lightEffect.opCode, type: lightEffect.sceneType, cmdVersion: lightEffect.cmdVersion, }; })); }); return effects; }, []); } catch (error) { this.logger.error('Unable to retrieve device light effects', error); return undefined; } } async getDeviceScenes(oauth, model, goodsType, deviceId) { try { this.logger.log(`Retrieving light scenes for device ${model} ${deviceId} from Govee REST API`); const response = await (0, utils_1.request)(this.config.sceneUrl, this.config.headers(oauth), { sku: model, goodsType, device: deviceId, }).get(scene_list_response_1.SceneListResponse); return response.data.sceneData.categories.reduce((effects, category) => { effects.push(...category.scenes.map((scene) => ({ name: scene.name, code: scene.code, opCode: scene.opCode, type: scene.type, cmdVersion: 0, }))); return effects; }, []); } catch (error) { this.logger.error('Unable to retrieve device light effects', error); return undefined; } } }; exports.GoveeEffectService = GoveeEffectService; __decorate([ (0, _ultimate_govee_persist_1.PersistResult)({ filename: 'govee.{1}.effects.json', }), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String, Number, String]), __metadata("design:returntype", Promise) ], GoveeEffectService.prototype, "getEffects", null); exports.GoveeEffectService = GoveeEffectService = GoveeEffectService_1 = __decorate([ (0, common_1.Injectable)(), __param(0, (0, common_1.Inject)(govee_effect_config_1.GoveeEffectConfig.KEY)), __metadata("design:paramtypes", [void 0]) ], GoveeEffectService); //# sourceMappingURL=govee-effect.service.js.map