Files
zigbee2mqtt/lib/model/device.ts
T
Valentin cd5dd39971 Dynamically expose attributes (#10132)
* Dynamically expose attributes

* Rollback options in configure step

Use event instead, as proposed in https://github.com/Koenkk/zigbee2mqtt/pull/10132/files#r771801648

* Simplify code

* Switch to already existing event

* Fix all unit tests

* Remove redundant code

* Perfect rollback

* Fix typescript types

* Updates

* Updates

* Updates

* updates

* Improve

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-12-22 19:31:41 +00:00

83 lines
2.8 KiB
TypeScript

/* eslint-disable brace-style */
import * as settings from '../util/settings';
import zigbeeHerdsmanConverters from 'zigbee-herdsman-converters';
export default class Device {
public zh: zh.Device;
private _definition: zhc.Definition;
get ieeeAddr(): string {return this.zh.ieeeAddr;}
get ID(): string {return this.zh.ieeeAddr;}
get settings(): DeviceSettings {return {...settings.get().device_options, ...settings.getDevice(this.ieeeAddr)};}
get name(): string {
return this.zh.type === 'Coordinator' ? 'Coordinator' : this.settings?.friendly_name || this.ieeeAddr;
}
get definition(): zhc.Definition {
if (!this._definition && !this.zh.interviewing) {
this._definition = zigbeeHerdsmanConverters.findByDevice(this.zh);
}
return this._definition;
}
constructor(device: zh.Device) {
this.zh = device;
}
exposes(): zhc.DefinitionExpose[] {
/* istanbul ignore if */
if (typeof this.definition.exposes == 'function') {
return this.definition.exposes(this.zh, this.settings);
} else {
return this.definition.exposes;
}
}
ensureInSettings(): void {
if (this.zh.type !== 'Coordinator' && !settings.getDevice(this.zh.ieeeAddr)) {
settings.addDevice(this.zh.ieeeAddr);
}
}
endpoint(key?: string | number): zh.Endpoint {
let endpoint: zh.Endpoint;
if (key == null || key == '') key = 'default';
if (!isNaN(Number(key))) {
endpoint = this.zh.getEndpoint(Number(key));
} else if (this.definition?.endpoint) {
const ID = this.definition?.endpoint?.(this.zh)[key];
if (ID) endpoint = this.zh.getEndpoint(ID);
else if (key === 'default') endpoint = this.zh.endpoints[0];
else return null;
} else {
/* istanbul ignore next */
if (key !== 'default') return null;
endpoint = this.zh.endpoints[0];
}
return endpoint;
}
endpointName(endpoint: zh.Endpoint): string {
let name = null;
if (this.definition?.endpoint) {
name = Object.entries(this.definition?.endpoint(this.zh)).find((e) => e[1] == endpoint.ID)[0];
}
/* istanbul ignore next */
return name === 'default' ? null : name;
}
isXiaomi(): boolean {
const xiaomiManufacturerID = [4151, 4447];
/* istanbul ignore next */
return this.zh.modelID !== 'lumi.router' && xiaomiManufacturerID.includes(this.zh.manufacturerID) &&
(!this.zh.manufacturerName || !this.zh.manufacturerName.startsWith('Trust'));
}
isIkeaTradfri(): boolean {return this.zh.manufacturerID === 4476;}
isDevice(): this is Device {return true;}
/* istanbul ignore next */
isGroup(): this is Group {return false;}
}