Allow settings permit_join via home assistant switch.

This commit is contained in:
Koen Kanters
2018-04-24 19:30:56 +02:00
parent e0feacea0b
commit 3322d6cb20
3 changed files with 76 additions and 33 deletions
+56 -27
View File
@@ -5,6 +5,7 @@ const settings = require('./util/settings');
const deviceMapping = require('./devices');
const zigbee2mqtt = require('./converters/zigbee2mqtt');
const mqtt2zigbee = require('./converters/mqtt2zigbee');
const homeassistant = require('./homeassistant');
class Controller {
@@ -24,24 +25,45 @@ class Controller {
logger.error('Failed to start');
} else {
this.mqtt.connect(this.handleMQTTMessage, () => {
// Home assistant MQTT discovery on startup.
if (settings.get().homeassistant) {
const devices = this.zigbee.getAllClients();
devices.forEach((device) => {
const mappedModel = deviceMapping[device.modelId];
if (mappedModel && mappedModel.homeassistant && !this.hassDiscoveryCache[device.ieeeAddr]) {
this.homeassistantDiscover(mappedModel, device, settings.getDevice(device.ieeeAddr).friendly_name);
this.hassDiscoveryCache[device.ieeeAddr] = true;
}
});
}
this.handleStarted();
});
}
});
}
handleStarted() {
// Home assistant MQTT discovery on startup.
if (settings.get().homeassistant) {
// MQTT discovery of all paired devices on startup.
const devices = this.zigbee.getAllClients();
devices.forEach((device) => {
const mappedModel = deviceMapping[device.modelId];
if (mappedModel && mappedModel.homeassistant && !this.hassDiscoveryCache[device.ieeeAddr]) {
this.homeassistantDiscover(
mappedModel.homeassistant,
device.ieeeAddr,
settings.getDevice(device.ieeeAddr).friendly_name
);
this.hassDiscoveryCache[device.ieeeAddr] = true;
}
});
// MQTT discovery of zigbee2mqtt permit join switch.
this.homeassistantDiscover([homeassistant.zigbee2mqtt_permit_join], 'zigbee2mqtt_permit_join', 'zigbee2mqtt_permit_join');
this.mqtt.publish('permit_join', JSON.stringify({state: settings.get().permit_join ? '"ON"' : '"OFF"'}), true);
}
// Enable zigbee join.
if (settings.get().permit_join) {
logger.warn('`permit_join` set to `true` in configuration.yaml.')
logger.warn('Allowing new devices to join.');
logger.warn('Set `permit_join` to `false` once you joined all devices.');
this.zigbee.permitJoin(true);
}
}
stop(callback) {
this.mqtt.disconnect();
this.zigbee.stop(callback);
@@ -98,7 +120,7 @@ class Controller {
// Home assistant MQTT discovery
if (settings.get().homeassistant && mappedModel.homeassistant &&
!this.hassDiscoveryCache[device.ieeeAddr]) {
this.homeassistantDiscover(mappedModel, device, friendlyName);
this.homeassistantDiscover(mappedModel.homeassistant, device.ieeeAddr, friendlyName);
this.hassDiscoveryCache[device.ieeeAddr] = true;
}
@@ -148,13 +170,6 @@ class Controller {
handleMQTTMessage(topic, message) {
const friendlyName = topic.split('/')[1];
// Map friendlyName to deviceID.
const deviceID = Object.keys(settings.get().devices).find((id) => settings.getDevice(id).friendly_name === friendlyName);
if (!deviceID) {
logger.error(`Cannot handle '${topic}' because deviceID of '${friendlyName}' cannot be found`);
return;
}
// Convert the MQTT message to a Zigbee message.
let json = null;
try {
@@ -164,6 +179,20 @@ class Controller {
json = {state: message.toString()};
}
// Check if permit_join
if (friendlyName === 'zigbee2mqtt_permit_join') {
this.zigbee.permitJoin(json.state === 'ON' ? true : false);
this.mqtt.publish(friendlyName, JSON.stringify({state: json.state}), true);
return;
}
// Map friendlyName to deviceID.
const deviceID = Object.keys(settings.get().devices).find((id) => settings.getDevice(id).friendly_name === friendlyName);
if (!deviceID) {
logger.error(`Cannot handle '${topic}' because deviceID of '${friendlyName}' cannot be found`);
return;
}
Object.keys(json).forEach((key) => {
// Find converter for this key.
const converter = mqtt2zigbee[key];
@@ -188,16 +217,16 @@ class Controller {
});
}
homeassistantDiscover(mappedModel, device, friendlyName) {
mappedModel.homeassistant.forEach((discover) => {
const topic = `${discover.type}/${device.ieeeAddr}/${discover.object_id}/config`;
const payload = discover.discovery_payload;
homeassistantDiscover(configurations, deviceID, friendlyName) {
configurations.forEach((config) => {
const topic = `${config.type}/${deviceID}/${config.object_id}/config`;
const payload = config.discovery_payload;
payload.state_topic = `${settings.get().mqtt.base_topic}/${friendlyName}`;
payload.availability_topic = `${settings.get().mqtt.base_topic}/bridge/state`;
// Set unique names in cases this device produces multiple entities in homeassistant.
if (mappedModel.homeassistant.length > 1) {
payload.name = `${friendlyName}_${discover.object_id}`;
if (configurations.length > 1) {
payload.name = `${friendlyName}_${config.object_id}`;
} else {
payload.name = friendlyName;
}
+13
View File
@@ -128,6 +128,19 @@ const homeassistant = {
command_topic: true
}
},
// zigbee2mqtt
'zigbee2mqtt_permit_join': {
type: 'switch',
object_id: 'switch',
discovery_payload: {
payload_off: 'OFF',
payload_on: 'ON',
value_template: '{{ value_json.state }}',
command_topic: true,
icon: 'mdi:router-wireless',
}
},
};
module.exports = homeassistant;
+7 -6
View File
@@ -62,15 +62,16 @@ class Zigbee {
});
}
});
}
// Allow or disallow new devices to join the network.
if (settings.get().permit_join) {
logger.warn('`permit_join` set to `true` in configuration.yaml.')
logger.warn('Allowing new devices to join.');
logger.warn('Set `permit_join` to `false` once you joined all devices.');
permitJoin(permit) {
if (permit) {
logger.info('Zigbee: allowing new devices to join.');
} else {
logger.info('Zigbee: disabling joining new devices.');
}
this.shepherd.permitJoin(settings.get().permit_join ? 255 : 0, (error) => {
this.shepherd.permitJoin(permit ? 255 : 0, (error) => {
if (error) {
logger.info(error);
}