Isolate legacy MQTT log. #3281

This commit is contained in:
Koen Kanters
2020-04-05 18:36:08 +02:00
parent 9df1589361
commit 552eec7baa
6 changed files with 229 additions and 65 deletions
+61 -21
View File
@@ -63,7 +63,10 @@ class BridgeLegacy extends BaseExtension {
assert(entity, `Entity '${message}' does not exist`);
settings.whitelistDevice(entity.ID);
logger.info(`Whitelisted '${entity.friendlyName}'`);
this.mqtt.log('device_whitelisted', {friendly_name: entity.friendlyName});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: 'device_whitelisted', message: {friendly_name: entity.friendlyName}}),
);
} catch (error) {
logger.error(`Failed to whitelist '${message}' '${error}'`);
}
@@ -174,16 +177,18 @@ class BridgeLegacy extends BaseExtension {
if (topic.split('/').pop() == 'get') {
this.mqtt.publish(`bridge/config/devices`, JSON.stringify(devices), {});
} else {
this.mqtt.log('devices', devices);
this.mqtt.publish('bridge/log', JSON.stringify({type: 'devices', message: devices}));
}
}
groups(topic, message) {
this.mqtt.log('groups', settings.getGroups().map((g) => {
const payload = settings.getGroups().map((g) => {
const group = {...g};
delete group.friendlyName;
return group;
}));
});
this.mqtt.publish('bridge/log', JSON.stringify({type: 'groups', message: payload}));
}
rename(topic, message) {
@@ -223,7 +228,11 @@ class BridgeLegacy extends BaseExtension {
const entity = this.zigbee.resolveEntity(to);
const eventData = isGroup ? {group: entity.group} : {device: entity.device};
this.eventBus.emit(`${isGroup ? 'group' : 'device'}Renamed`, eventData);
this.mqtt.log(`${isGroup ? 'group' : 'device'}_renamed`, {from, to});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `${isGroup ? 'group' : 'device'}_renamed`, message: {from, to}}),
);
} catch (error) {
logger.error(`Failed to rename - ${from} to ${to}`);
}
@@ -254,7 +263,7 @@ class BridgeLegacy extends BaseExtension {
const group = settings.addGroup(name, id);
this.zigbee.createGroup(group.ID);
this.mqtt.log('group_added', name);
this.mqtt.publish('bridge/log', JSON.stringify({type: `group_added`, message: name}));
logger.info(`Added group '${name}'`);
}
@@ -264,7 +273,7 @@ class BridgeLegacy extends BaseExtension {
assert(entity && entity.type === 'group', `Group '${message}' does not exist`);
settings.removeGroup(message);
entity.group.removeFromDatabase();
this.mqtt.log('group_removed', message);
this.mqtt.publish('bridge/log', JSON.stringify({type: `group_removed`, message}));
logger.info(`Removed group '${name}'`);
}
@@ -291,7 +300,7 @@ class BridgeLegacy extends BaseExtension {
if (!entity) {
logger.error(`Cannot ${lookup[action][2]}, device '${message}' does not exist`);
this.mqtt.log(`device_${lookup[action][0]}_failed`, message);
this.mqtt.publish('bridge/log', JSON.stringify({type: `device_${lookup[action][0]}_failed`, message}));
return;
}
@@ -306,7 +315,7 @@ class BridgeLegacy extends BaseExtension {
this.state.remove(entity.settings.ID);
logger.info(`Successfully ${lookup[action][0]} ${entity.settings.friendlyName}`);
this.mqtt.log(`device_${lookup[action][0]}`, message);
this.mqtt.publish('bridge/log', JSON.stringify({type: `device_${lookup[action][0]}`, message}));
};
try {
@@ -323,7 +332,7 @@ class BridgeLegacy extends BaseExtension {
// eslint-disable-next-line
logger.error(`See https://www.zigbee2mqtt.io/information/mqtt_topics_and_message_structure.html#zigbee2mqttbridgeconfigremove for more info`);
this.mqtt.log(`device_${lookup[action][0]}_failed`, message);
this.mqtt.publish('bridge/log', JSON.stringify({type: `device_${lookup[action][0]}_failed`, message}));
}
if (action === 'ban') {
@@ -374,47 +383,78 @@ class BridgeLegacy extends BaseExtension {
}
if (type === 'deviceJoined') {
this.mqtt.log('device_connected', {friendly_name: resolvedEntity.name});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_connected`, message: {friendly_name: resolvedEntity.name}}),
);
} else if (type === 'deviceInterview') {
if (data.status === 'successful') {
if (resolvedEntity.definition) {
const {vendor, description, model} = resolvedEntity.definition;
const log = {friendly_name: resolvedEntity.name, model, vendor, description, supported: true};
this.mqtt.log('pairing', 'interview_successful', log);
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `pairing`, message: 'interview_successful', meta: log}),
);
} else {
this.mqtt.log('pairing', 'interview_successful',
{friendly_name: resolvedEntity.name, supported: false});
const meta = {friendly_name: resolvedEntity.name, supported: false};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `pairing`, message: 'interview_successful', meta}),
);
}
} else if (data.status === 'failed') {
this.mqtt.log('pairing', 'interview_failed', {friendly_name: resolvedEntity.name});
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `pairing`, message: 'interview_failed', meta}),
);
} else {
/* istanbul ignore else */
if (data.status === 'started') {
this.mqtt.log('pairing', 'interview_started', {friendly_name: resolvedEntity.name});
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `pairing`, message: 'interview_started', meta}),
);
}
}
} else if (type === 'deviceAnnounce') {
this.mqtt.log('device_announced', 'announce', {friendly_name: resolvedEntity.name});
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish('bridge/log', JSON.stringify({type: `device_announced`, message: 'announce', meta}));
} else {
/* istanbul ignore else */
if (type === 'deviceLeave') {
const name = resolvedEntity ? resolvedEntity.name : data.ieeeAddr;
this.mqtt.log('device_removed', 'left_network', {friendly_name: name});
const meta = {friendly_name: name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_removed`, message: 'left_network', meta}),
);
}
}
}
async touchlinkFactoryReset() {
logger.info('Starting touchlink factory reset...');
this.mqtt.log('touchlink', 'reset_started', {status: 'started'});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `touchlink`, message: 'reset_started', meta: {status: 'started'}}),
);
const result = await this.zigbee.touchlinkFactoryReset();
if (result) {
logger.info('Successfully factory reset device through Touchlink');
this.mqtt.log('touchlink', 'reset_success', {status: 'success'});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `touchlink`, message: 'reset_success', meta: {status: 'success'}}),
);
} else {
logger.warn('Failed to factory reset device through Touchlink');
this.mqtt.log('touchlink', 'reset_failed', {status: 'failed'});
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `touchlink`, message: 'reset_failed', meta: {status: 'failed'}}),
);
}
}
}
+27 -9
View File
@@ -61,26 +61,44 @@ class DeviceBind extends BaseExtension {
`Successfully ${type === 'bind' ? 'bound' : 'unbound'} cluster '${cluster}' from ` +
`'${sourceName}' to '${targetName}'`,
);
this.mqtt.log(
`device_${type}`,
{from: sourceName, to: targetName, cluster},
);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const message = {from: sourceName, to: targetName, cluster};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_${type}`, message}),
);
}
} catch (error) {
logger.error(
`Failed to ${type} cluster '${cluster}' from '${sourceName}' to ` +
`'${targetName}' (${error})`,
);
this.mqtt.log(
`device_${type}_failed`,
{from: sourceName, to: targetName, cluster},
);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const message = {from: sourceName, to: targetName, cluster};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_${type}_failed`, message}),
);
}
}
}
}
if (!attemptedToBindSomething) {
logger.error(`Nothing to ${type} from '${sourceName}' to '${targetName}'`);
this.mqtt.log(`device_${type}_failed`, {from: sourceName, to: targetName});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const message = {from: sourceName, to: targetName};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_${type}_failed`, message}),
);
}
}
}
}
+18 -2
View File
@@ -59,7 +59,15 @@ class EntityPublish extends BaseExtension {
const entity = this.zigbee.resolveEntity(entityName);
if (!entity) {
this.mqtt.log('entity_not_found', {friendly_name: entityName});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const message = {friendly_name: entityName};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `entity_not_found`, message}),
);
}
logger.error(`Entity '${entityName}' is unknown`);
return;
}
@@ -211,7 +219,15 @@ class EntityPublish extends BaseExtension {
`Publish '${topic.type}' '${key}' to '${entity.name}' failed: '${error}'`;
logger.error(message);
logger.debug(error.stack);
this.mqtt.log('zigbee_publish_error', message, {friendly_name: entity.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {friendly_name: entity.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `zigbee_publish_error`, message, meta}),
);
}
}
usedConverters.push(converter);
+47 -9
View File
@@ -144,9 +144,16 @@ class Groups extends BaseExtension {
if (!group || group.type !== 'group') {
logger.error(`Group '${topicMatch[1]}' does not exist`);
this.mqtt.log(
`device_group_${type}_failed`,
{friendly_name: message, group: topicMatch[1], error: 'group doesn\'t exists'});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: message, group: topicMatch[1], error: 'group doesn\'t exists'};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_group_${type}_failed`, message: payload}),
);
}
return;
}
} else if (topic.match(topicRegexRemoveAll)) {
@@ -158,9 +165,16 @@ class Groups extends BaseExtension {
const entity = this.zigbee.resolveEntity(message);
if (!entity || !entity.type === 'device') {
logger.error(`Device '${message}' does not exist`);
this.mqtt.log(
`device_group_${type}_failed`,
{friendly_name: message, group: topicMatch[1], error: 'entity doesn\'t exists'});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: message, group: topicMatch[1], error: 'entity doesn\'t exists'};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_group_${type}_failed`, message: payload}),
);
}
return;
}
@@ -188,18 +202,42 @@ class Groups extends BaseExtension {
logger.info(`Adding '${entity.name}' to '${group.name}'`);
await entity.endpoint.addToGroup(group.group);
settings.addDeviceToGroup(group.settings.ID, keys);
this.mqtt.log('device_group_add', {friendly_name: entity.name, group: group.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: entity.name, group: group.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_group_add`, message: payload}),
);
}
} else if (type === 'remove') {
logger.info(`Removing '${entity.name}' from '${group.name}'`);
await entity.endpoint.removeFromGroup(group.group);
settings.removeDeviceFromGroup(group.settings.ID, keys);
this.mqtt.log('device_group_remove', {friendly_name: entity.name, group: group.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: entity.name, group: group.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_group_remove`, message: payload}),
);
}
} else { // remove_all
logger.info(`Removing '${entity.name}' from all groups`);
await entity.endpoint.removeFromAllGroups();
for (const settingsGroup of settings.getGroups()) {
settings.removeDeviceFromGroup(settingsGroup.ID, keys);
this.mqtt.log('device_group_remove_all', {friendly_name: entity.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: entity.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `device_group_remove_all`, message: payload}),
);
}
}
}
}
+76 -14
View File
@@ -36,10 +36,15 @@ class OTAUpdate extends BaseExtension {
if (available) {
const message = `Update available for '${resolvedEntity.settings.friendly_name}'`;
logger.info(message);
this.mqtt.log(
'ota_update', message,
{status: 'available', device: resolvedEntity.settings.friendly_name},
);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: 'available', device: resolvedEntity.settings.friendly_name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
}
}
@@ -77,7 +82,16 @@ class OTAUpdate extends BaseExtension {
if (!device.definition || !device.definition.ota) {
const message = `Device '${device.name}' does not support OTA updates`;
logger.error(message);
this.mqtt.log('ota_update', message, {status: `not_supported`, device: device.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `not_supported`, device: device.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
return;
}
@@ -91,25 +105,59 @@ class OTAUpdate extends BaseExtension {
if (type === 'check') {
const message = `Checking if update available for '${device.name}'`;
logger.info(message);
this.mqtt.log('ota_update', message, {status: `checking_if_available`, device: device.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `checking_if_available`, device: device.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
try {
const available = await device.definition.ota.isUpdateAvailable(device.device, logger);
const message=(available ?
`Update available for '${device.name}'` : `No update available for '${device.name}'`);
logger.info(message);
const meta = {status: available ? 'available' : 'not_available', device: device.name};
this.mqtt.log('ota_update', message, meta);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: available ? 'available' : 'not_available', device: device.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
this.publishEntityState(device.device.ieeeAddr, {update_available: available});
this.lastChecked[device.device.ieeeAddr] = Date.now();
} catch (error) {
const message = `Failed to check if update available for '${device.name}' (${error.message})`;
logger.error(message);
this.mqtt.log('ota_update', message, {status: `check_failed`, device: device.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `check_failed`, device: device.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
}
} else { // type === 'update'
const message = `Updating '${device.name}' to latest firmware`;
logger.info(message);
this.mqtt.log('ota_update', message, {status: `update_in_progress`, device: device.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_in_progress`, device: device.name};
this.mqtt.publish(
'bridge/log',
JSON.stringify({type: `ota_update`, message, meta}),
);
}
try {
const onProgress = (progress, remaining) => {
let message = `Update of '${device.name}' at ${progress}%`;
@@ -118,7 +166,12 @@ class OTAUpdate extends BaseExtension {
}
logger.info(message);
this.mqtt.log('ota_update', message, {status: `update_progress`, device: device.name, progress});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_progress`, device: device.name, progress};
this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta}));
}
};
const from_ = await this.readSoftwareBuildIDAndDateCode(device.device, false);
@@ -127,13 +180,22 @@ class OTAUpdate extends BaseExtension {
const [fromS, toS] = [JSON.stringify(from_), JSON.stringify(to)];
const message = `Finished update of '${device.name}'` + (to ? `, from '${fromS}' to '${toS}'` : ``);
logger.info(message);
const meta = {status: `update_succeeded`, device: device.name, from: from_, to};
this.mqtt.log('ota_update', message, meta);
this.publishEntityState(device.device.ieeeAddr, {update_available: false});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_succeeded`, device: device.name, from: from_, to};
this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta}));
}
} catch (error) {
const message = `Update of '${device.name}' failed (${error.message})`;
logger.error(message);
this.mqtt.log('ota_update', message, {status: `update_failed`, device: device.name});
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_failed`, device: device.name};
this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta}));
}
}
}
-10
View File
@@ -111,16 +111,6 @@ class MQTT extends events.EventEmitter {
this.client.publish(topic, payload, options, () => resolve());
});
}
log(type, message, meta=null) {
const payload = {type, message};
if (meta) {
payload.meta = meta;
}
this.publish('bridge/log', JSON.stringify(payload), {retain: false});
}
}
module.exports = MQTT;