Merge pull request #99 from ciotlosm/add_device_remove

Add device remove
This commit is contained in:
Koen Kanters 2018-06-10 17:41:25 +02:00 committed by GitHub
commit b7252379b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 4 deletions

View File

@ -328,6 +328,40 @@ class Controller {
});
this.mqtt.log('devices', devices);
} else if (option === 'remove') {
message = message.toString();
const IDByFriendlyName = settings.getIDByFriendlyName(message);
const deviceID = IDByFriendlyName ? IDByFriendlyName : message;
const device = this.zigbee.getDevice(deviceID);
const cleanup = () => {
// Clear Home Assistant MQTT discovery message
if (settings.get().homeassistant && device) {
const mappedModel = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (mappedModel) {
homeassistant.clear(deviceID, mappedModel.model, this.mqtt);
}
}
// Remove from configuration.yaml
settings.removeDevice(deviceID);
logger.info(`Successfully removed ${deviceID}`);
this.mqtt.log('device_removed', message);
};
// Remove from zigbee network.
if (device) {
this.zigbee.removeDevice(deviceID, (error) => {
if (!error) {
cleanup();
} else {
logger.error(`Failed to remove ${deviceID}`);
}
});
} else {
cleanup();
}
} else {
logger.warn(`Cannot handle MQTT config option '${option}' with message '${message}'`);
}
@ -338,9 +372,7 @@ class Controller {
const topicPrefix = withPrefix ? topic.split('/')[2] : '';
// Map friendlyName to deviceID.
const deviceID = Object.keys(settings.get().devices).find((id) =>
settings.getDevice(id).friendly_name === friendlyName
);
const deviceID = settings.getIDByFriendlyName(friendlyName);
if (!deviceID) {
logger.error(`Cannot handle '${topic}' because deviceID of '${friendlyName}' cannot be found`);

View File

@ -296,7 +296,23 @@ function discover(deviceID, model, mqtt) {
discovered[deviceID] = true;
}
function clear(deviceID, model, mqtt) {
// Check if there are configs.
if (!mapping[model]) {
return;
}
mapping[model].forEach((config) => {
const topic = `${config.type}/${deviceID}/${config.object_id}/config`;
const payload = '';
mqtt.publish(topic, payload, {retain: true, qos: 0}, null, 'homeassistant');
});
discovered[deviceID] = false;
}
module.exports = {
mapping: mapping,
discover: (deviceID, model, mqtt) => discover(deviceID, model, mqtt),
clear: (deviceID, model, mqtt) => clear(deviceID, model, mqtt),
};

View File

@ -27,9 +27,28 @@ function addDevice(id) {
writeRead();
}
function removeDevice(id) {
if (settings.devices && settings.devices[id]) {
delete settings.devices[id];
writeRead();
}
}
function getIDByFriendlyName(friendlyName) {
if (!settings.devices) {
return null;
}
return Object.keys(settings.devices).find((id) =>
settings.devices[id].friendly_name === friendlyName
);
}
module.exports = {
get: () => settings,
write: () => write(),
getDevice: (id) => settings.devices ? settings.devices[id] : false,
getDevice: (id) => settings.devices ? settings.devices[id] : null,
addDevice: (id) => addDevice(id),
removeDevice: (id) => removeDevice(id),
getIDByFriendlyName: (friendlyName) => getIDByFriendlyName(friendlyName),
};

View File

@ -109,6 +109,28 @@ class Zigbee {
return this.shepherd.list().filter((device) => device.type !== 'Coordinator');
}
removeDevice(deviceID, callback) {
this.shepherd.remove(deviceID, (error) => {
if (error) {
logger.warn(`Failed to remove '${deviceID}', trying force remove...`);
this._forceRemove(deviceID, callback);
} else {
callback(null);
}
});
}
_forceRemove(deviceID, callback) {
const device = this.shepherd._findDevByAddr(deviceID);
if (device) {
return this.shepherd._unregisterDev(device, (error) => callback(error));
} else {
logger.warn(`Could not find ${deviceID} for force removal`);
callback(true);
}
}
ping(deviceID) {
const device = this.shepherd._findDevByAddr(deviceID);