@felixgeelhaar/govee-api-client
Version:
Enterprise-grade TypeScript client library for the Govee Developer REST API
138 lines • 5.05 kB
JavaScript
export class GoveeDevice {
constructor(deviceId, sku, deviceName, capabilities) {
this.validateDeviceId(deviceId);
this.validateSku(sku);
this.validateDeviceName(deviceName);
this.validateCapabilities(capabilities);
this._deviceId = deviceId;
this._sku = sku;
this._deviceName = deviceName;
this._capabilities = [...capabilities];
this._controllable = this.deriveControllable(capabilities);
this._retrievable = this.deriveRetrievable(capabilities);
this._supportedCmds = this.deriveSupportedCommands(capabilities);
}
validateDeviceId(deviceId) {
if (!deviceId || typeof deviceId !== 'string' || deviceId.trim().length === 0) {
throw new Error('Device ID must be a non-empty string');
}
}
validateSku(sku) {
if (!sku || typeof sku !== 'string' || sku.trim().length === 0) {
throw new Error('SKU must be a non-empty string');
}
}
validateDeviceName(deviceName) {
if (!deviceName || typeof deviceName !== 'string' || deviceName.trim().length === 0) {
throw new Error('Device name must be a non-empty string');
}
}
validateCapabilities(capabilities) {
if (!Array.isArray(capabilities)) {
throw new Error('Capabilities must be an array');
}
for (const capability of capabilities) {
if (!capability.type ||
typeof capability.type !== 'string' ||
capability.type.trim().length === 0) {
throw new Error('All capabilities must have non-empty type strings');
}
}
}
deriveControllable(capabilities) {
// Device is controllable if it has any control capabilities
return capabilities.some(cap => cap.type.includes('on_off') ||
cap.type.includes('range') ||
cap.type.includes('color_setting'));
}
deriveRetrievable(capabilities) {
// Most devices with capabilities are retrievable
return capabilities.length > 0;
}
deriveSupportedCommands(capabilities) {
const commands = new Set();
for (const capability of capabilities) {
if (capability.type.includes('on_off'))
commands.add('turn');
if (capability.type.includes('range') && capability.instance === 'brightness')
commands.add('brightness');
if (capability.type.includes('color_setting')) {
if (capability.instance === 'colorRgb')
commands.add('color');
if (capability.instance === 'colorTemperatureK')
commands.add('colorTem');
}
}
return Array.from(commands);
}
get deviceId() {
return this._deviceId;
}
get model() {
return this._sku; // For backward compatibility
}
get sku() {
return this._sku;
}
get capabilities() {
return Object.freeze([...this._capabilities]);
}
get deviceName() {
return this._deviceName;
}
get controllable() {
return this._controllable;
}
get retrievable() {
return this._retrievable;
}
get supportedCmds() {
return Object.freeze([...this._supportedCmds]);
}
equals(other) {
return this._deviceId === other._deviceId && this._sku === other._sku;
}
toString() {
return `GoveeDevice(${this._deviceId}, ${this._sku}, "${this._deviceName}")`;
}
supportsCommand(command) {
return this._supportedCmds.includes(command);
}
canControl() {
return this._controllable;
}
canRetrieve() {
return this._retrievable;
}
toObject() {
return {
deviceId: this._deviceId,
model: this._sku,
deviceName: this._deviceName,
controllable: this._controllable,
retrievable: this._retrievable,
supportedCmds: [...this._supportedCmds],
};
}
static fromObject(obj) {
// Convert old format to new capabilities format for backward compatibility
const capabilities = [];
if (obj.supportedCmds.includes('turn')) {
capabilities.push({ type: 'devices.capabilities.on_off', instance: 'powerSwitch' });
}
if (obj.supportedCmds.includes('brightness')) {
capabilities.push({ type: 'devices.capabilities.range', instance: 'brightness' });
}
if (obj.supportedCmds.includes('color')) {
capabilities.push({ type: 'devices.capabilities.color_setting', instance: 'colorRgb' });
}
if (obj.supportedCmds.includes('colorTem')) {
capabilities.push({
type: 'devices.capabilities.color_setting',
instance: 'colorTemperatureK',
});
}
return new GoveeDevice(obj.deviceId, obj.model, obj.deviceName, capabilities);
}
}
//# sourceMappingURL=GoveeDevice.js.map