mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2024-11-16 18:39:09 -07:00
Refactor deviceAvailability.js
This commit is contained in:
parent
2ce2876f04
commit
1573687979
@ -4,18 +4,13 @@ const utils = require('../util/utils');
|
||||
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
|
||||
const BaseExtension = require('./baseExtension');
|
||||
|
||||
// Some EndDevices should be pinged
|
||||
// Pingable end devices, some end devices should be pinged
|
||||
// e.g. E11-G13 https://github.com/Koenkk/zigbee2mqtt/issues/775#issuecomment-453683846
|
||||
const pingableModels = [
|
||||
'E11-G13',
|
||||
'53170161',
|
||||
const pingableEndDevices = [
|
||||
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'E11-G13'),
|
||||
zigbeeHerdsmanConverters.devices.find((d) => d.model === '53170161'),
|
||||
];
|
||||
|
||||
const forcedPingable =
|
||||
zigbeeHerdsmanConverters.devices.filter((d) => pingableModels.includes(d.model));
|
||||
|
||||
const toZigbeeCandidates = ['state', 'brightness', 'color', 'color_temp'];
|
||||
|
||||
const Hours25 = 1000 * 60 * 60 * 25;
|
||||
|
||||
/**
|
||||
@ -29,22 +24,14 @@ class DeviceAvailability extends BaseExtension {
|
||||
this.timers = {};
|
||||
this.state = {};
|
||||
|
||||
// Initialize blacklist
|
||||
this.blacklist = settings.get().advanced.availability_blacklist.map((e) => {
|
||||
return settings.getEntity(e).ID;
|
||||
});
|
||||
|
||||
// Initialize whitelist
|
||||
this.whitelist = settings.get().advanced.availability_whitelist.map((e) => {
|
||||
return settings.getEntity(e).ID;
|
||||
});
|
||||
this.blacklist = settings.get().advanced.availability_blacklist.map((e) => settings.getEntity(e).ID);
|
||||
this.whitelist = settings.get().advanced.availability_whitelist.map((e) => settings.getEntity(e).ID);
|
||||
}
|
||||
|
||||
isAllowed(device) {
|
||||
inWhitelistOrNotInBlacklist(device) {
|
||||
const ieeeAddr = device.ieeeAddr;
|
||||
|
||||
const deviceSettings = settings.getDevice(ieeeAddr);
|
||||
const name = deviceSettings.friendly_name;
|
||||
const name = deviceSettings.friendlyName;
|
||||
|
||||
// Whitelist is not empty and device is in it, enable availability
|
||||
if (this.whitelist.length > 0) {
|
||||
@ -60,15 +47,12 @@ class DeviceAvailability extends BaseExtension {
|
||||
}
|
||||
|
||||
isPingable(device) {
|
||||
// Device is on forcedPingable-list, enable availability
|
||||
if (forcedPingable.find((d) => d.zigbeeModel.includes(device.modelID))) {
|
||||
if (pingableEndDevices.find((d) => d.zigbeeModel.includes(device.modelID))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Device is a mains powered router
|
||||
const result = utils.isRouter(device) && !utils.isBatteryPowered(device);
|
||||
|
||||
return result;
|
||||
return utils.isRouter(device) && !utils.isBatteryPowered(device);
|
||||
}
|
||||
|
||||
onMQTTConnected() {
|
||||
@ -76,7 +60,7 @@ class DeviceAvailability extends BaseExtension {
|
||||
// Mark all devices as online on start
|
||||
this.publishAvailability(device, true);
|
||||
|
||||
if (this.isAllowed(device)) {
|
||||
if (this.inWhitelistOrNotInBlacklist(device)) {
|
||||
if (this.isPingable(device)) {
|
||||
this.setTimerPingable(device);
|
||||
} else {
|
||||
@ -90,21 +74,20 @@ class DeviceAvailability extends BaseExtension {
|
||||
|
||||
async handleIntervalPingable(device) {
|
||||
// When a device is already unavailable, log the ping failed on 'debug' instead of 'error'.
|
||||
const entity = this.zigbee.resolveEntity(device.ieeeAddr);
|
||||
if (!entity) {
|
||||
const resolvedEntity = this.zigbee.resolveEntity(device.ieeeAddr);
|
||||
if (!resolvedEntity) {
|
||||
logger.debug(`Stop pinging '${device.ieeeAddr}', device is not known anymore`);
|
||||
return;
|
||||
}
|
||||
|
||||
const ieeeAddr = device.ieeeAddr;
|
||||
const level = this.state.hasOwnProperty(ieeeAddr) && !this.state[ieeeAddr] ? 'debug' : 'error';
|
||||
const level = this.state.hasOwnProperty(device.ieeeAddr) && !this.state[device.ieeeAddr] ? 'debug' : 'error';
|
||||
try {
|
||||
await device.ping();
|
||||
this.publishAvailability(device, true);
|
||||
logger.debug(`Successfully pinged '${entity.name}'`);
|
||||
logger.debug(`Successfully pinged '${resolvedEntity.name}'`);
|
||||
} catch (error) {
|
||||
this.publishAvailability(device, false);
|
||||
logger[level](`Failed to ping '${entity.name}'`);
|
||||
logger[level](`Failed to ping '${resolvedEntity.name}'`);
|
||||
} finally {
|
||||
this.setTimerPingable(device);
|
||||
}
|
||||
@ -112,12 +95,12 @@ class DeviceAvailability extends BaseExtension {
|
||||
|
||||
async handleIntervalNotPingable(device) {
|
||||
const ago = Date.now() - device.lastSeen;
|
||||
const entity = this.zigbee.resolveEntity(device.ieeeAddr);
|
||||
if (!entity || !device.lastSeen) {
|
||||
const resolvedEntity = this.zigbee.resolveEntity(device.ieeeAddr);
|
||||
if (!resolvedEntity || !device.lastSeen) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(`Non-pingable device '${entity.name}' was last seen '${ago / 1000}' seconds ago.`);
|
||||
logger.debug(`Non-pingable device '${resolvedEntity.name}' was last seen '${ago / 1000}' seconds ago.`);
|
||||
|
||||
if (ago > Hours25) {
|
||||
this.publishAvailability(device, false);
|
||||
@ -143,23 +126,19 @@ class DeviceAvailability extends BaseExtension {
|
||||
}
|
||||
|
||||
async onReconnect(device) {
|
||||
if (device && device.modelID) {
|
||||
const definition = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
|
||||
|
||||
if (definition) {
|
||||
const resolvedEntity = this.zigbee.resolveEntity(device);
|
||||
if (resolvedEntity && resolvedEntity.definition) {
|
||||
const used = [];
|
||||
try {
|
||||
for (const key of toZigbeeCandidates) {
|
||||
const converter = definition.toZigbee.find((tz) => tz.key.includes(key));
|
||||
for (const key of ['state', 'brightness', 'color', 'color_temp']) {
|
||||
const converter = resolvedEntity.definition.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`);
|
||||
}
|
||||
logger.error(`Failed to read state of '${resolvedEntity.name}' after reconnect`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,7 +150,7 @@ class DeviceAvailability extends BaseExtension {
|
||||
}
|
||||
|
||||
const deviceSettings = settings.getDevice(ieeeAddr);
|
||||
const name = deviceSettings ? deviceSettings.friendly_name : ieeeAddr;
|
||||
const name = deviceSettings ? deviceSettings.friendlyName : ieeeAddr;
|
||||
const topic = `${name}/availability`;
|
||||
const payload = available ? 'online' : 'offline';
|
||||
if (this.state[ieeeAddr] !== available) {
|
||||
@ -186,7 +165,7 @@ class DeviceAvailability extends BaseExtension {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isAllowed(device)) {
|
||||
if (this.inWhitelistOrNotInBlacklist(device)) {
|
||||
this.publishAvailability(data.device, true);
|
||||
|
||||
if (this.isPingable(device)) {
|
||||
|
Loading…
Reference in New Issue
Block a user