Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
this.error('device unknown ' + name + ' ' + ieeeAddr);
return;
}
}
let model;
let converters;
if (isGroup) {
converters = groupConverters;
} else {
// Map device to a model
if (this.models.has(device.modelID)) {
model = this.models.get(device.modelID);
} else {
model = herdsmanConverters.findByZigbeeModel(device.modelID);
this.models.set(device.modelID, model);
}
if (!model) {
this.warn(`Device with modelID '${device.modelID}' is not supported.`);
this.warn('Please see: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html');
return;
}
converters = model.toZigbee;
}
// TODO understand postfix
let endpoint;
// Determine endpoint to publish to.
if (typeof model.endpoint !== 'undefined') {
async onMQTTConnected() {
this.mqtt.subscribe(this.statusTopic);
// MQTT discovery of all paired devices on startup.
for (const device of this.zigbee.getClients()) {
const mappedModel = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
if (mappedModel) {
this.discover(device.ieeeAddr, mappedModel, true);
}
}
}
async onZigbeeStarted() {
this.coordinatorEndpoint = this.zigbee.getDevicesByType('Coordinator')[0].getEndpoint(1);
for (const device of this.zigbee.getClients()) {
const mappedDevice = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
const settingsDevice = settings.getDevice(device.ieeeAddr);
if (this.shouldConfigure(device, mappedDevice)) {
await this.configure(device, mappedDevice, settingsDevice);
}
}
}
RED.httpAdmin.get('/zigbee-shepherd/converters', RED.auth.needsPermission('zigbee.read'), (req, res) => {
const converters = herdsmanConverters.findByZigbeeModel(req.query.modelID);
res.status(200).send(JSON.stringify({supports: converters.supports || ''}));
});
callOnEvent(device, type, data, mappedDevice) {
if (!mappedDevice) {
mappedDevice = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
}
if (mappedDevice && mappedDevice.onEvent) {
mappedDevice.onEvent(type, data, device);
}
}
}
return {
type: 'device', device, settings: entity, mapped, endpoint, name: entity.friendlyName,
isDefaultEndpoint, endpointName,
};
} else {
let group = this.getGroupByID(entity.ID);
if (!group) group = this.createGroup(entity.ID);
return {type: 'group', group, settings: entity, name: entity.friendlyName};
}
} else {
const setting = settings.getEntity(key.ieeeAddr);
return {
type: 'device',
device: key,
settings: setting,
mapped: zigbeeHerdsmanConverters.findByZigbeeModel(key.modelID),
name: setting ? setting.friendlyName : (key.type === 'Coordinator' ? 'Coordinator' : key.ieeeAddr),
};
}
}
postfix = Number(postfixByNumber[1]);
}
if (postfix) {
key = key.replace(`/${postfix}`, '');
}
const entity = settings.getEntity(key);
if (!entity) {
return null;
} else if (entity.type === 'device') {
const device = this.getDeviceByIeeeAddr(entity.ID);
if (!device) {
return null;
}
const mapped = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
const endpoints = mapped && mapped.endpoint ? mapped.endpoint(device) : null;
let isDefaultEndpoint = true;
let endpoint;
if (postfix) {
isDefaultEndpoint = false;
if (postfixByNumber) {
endpoint = device.getEndpoint(postfix);
} else {
assert(mapped != null, `Postfix '${postfix}' is given but device is unsupported`);
assert(endpoints != null, `Postfix '${postfix}' is given but device defines no endpoints`);
const endpointID = endpoints[postfix];
assert(endpointID, `Postfix '${postfix}' is given but device has no such endpoint`);
endpoint = device.getEndpoint(endpointID);
}
} else if (endpoints && endpoints['default']) {
endpoint = device.getEndpoint(endpoints['default']);
async onReconnect(device) {
if (device && device.modelID) {
const mappedDevice = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
if (mappedDevice) {
const used = [];
try {
for (const key of toZigbeeCandidates) {
const converter = mappedDevice.toZigbee.find((tz) => tz.key.includes(key));
if (converter && !used.includes(converter)) {
await converter.convertGet(device.endpoints[0], key, {});
used.push(converter);
}
}
} catch (error) {
const entity = this.zigbee.resolveEntity(device.ieeeAddr);
logger.error(`Failed to read state of '${entity.name}' after reconnect`);
}
}
const doConfigure = device => {
if (!device || device.type === 'Coordinator') {
return;
}
if (device.meta.configureFails === this.maxConfigureTries) {
this.warn(`configure last try ${device.meta.name} ${device.ieeeAddr} after ${device.meta.configureFails} fails`);
} else if (device.meta.configureFails > this.maxConfigureTries) {
this.debug(`configure max tries exceeded for ${device.meta.name} ${device.ieeeAddr}`);
return;
}
const mappedDevice = shepherdConverters.findByZigbeeModel(device.modelID);
if (mappedDevice && mappedDevice.configure && device.meta.shouldConfigure && !configured.has(device.ieeeAddr) && !configuring.has(device.ieeeAddr)) {
this.debug(`configure ${device.ieeeAddr} ${device.meta.name} (try ${device.meta.configureFails})`);
configuring.add(device.ieeeAddr);
mappedDevice.configure(device, this.coordinatorEndpoint).then(() => {
this.log(`successfully configured ${this.logName(device)}`);
configured.add(device.ieeeAddr);
}).catch(err => {
this.warn(`configure failed ${this.logName(device)} ${err && err.message}`);
device.meta.configureFails += 1;
}).finally(() => {
configuring.delete(device.ieeeAddr);
this.configureReport(device);
});
} else {
this.configureReport(device);
}