@constructorfleet/ultimate-govee
Version:
Library for interacting with Govee devices written in Typescript.
154 lines • 7.48 kB
JavaScript
;
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