zigbee2mqtt/lib/extension/groups.js
2019-02-13 19:49:06 +01:00

104 lines
3.2 KiB
JavaScript

const settings = require('../util/settings');
const logger = require('../util/logger');
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/.+/(remove|add|remove_all)$`);
class Groups {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
}
onMQTTConnected() {
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/remove`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/add`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/remove_all`);
}
parseTopic(topic) {
if (!topic.match(topicRegex)) {
return null;
}
// Remove base from topic
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/group/`, '');
// Parse type from topic
const type = topic.substr(topic.lastIndexOf('/') + 1, topic.length);
// Remove type from topic
topic = topic.replace(`/${type}`, '');
return {friendly_name: topic, type: type};
}
onMQTTMessage(topic, message) {
topic = this.parseTopic(topic);
if (!topic) {
return false;
}
// Find ID of this group.
const groupID = settings.getGroupIDByFriendlyName(topic.friendly_name);
if (!groupID) {
logger.error(`Group with friendly_name '${topic.friendly_name}' doesn't exist`);
return;
}
if (groupID === 99) {
logger.error('Group 99 is reserved, please use a different groupID');
return;
}
// Map message to ieeeAddr and check if device exist.
message = message.toString();
const ieeeAddr = settings.getIeeeAddrByFriendlyName(message) || message;
if (!this.zigbee.getDevice(ieeeAddr)) {
logger.error(`Failed to find device '${message}'`);
return;
}
// Send command to the device.
let payload = null;
let cmd = null;
if (topic.type === 'add') {
payload = {groupid: groupID, groupname: ''};
cmd = 'add';
} else if (topic.type === 'remove') {
payload = {groupid: groupID};
cmd = 'remove';
} else if (topic.type === 'remove_all') {
payload = {};
cmd = 'removeAll';
}
const callback = (error, rsp) => {
if (error) {
logger.error(`Failed to ${topic.type} ${ieeeAddr} from ${topic.friendly_name}`);
} else {
logger.info(`Successfully ${topic.type} ${ieeeAddr} to ${topic.friendly_name}`);
// Log to MQTT
const log = {device: message};
if (['remove', 'add'].includes(topic.type)) {
log.group = topic.friendly_name;
}
this.mqtt.log(log);
}
};
this.zigbee.publish(
ieeeAddr, 'device', 'genGroups', cmd, 'functional',
payload, null, null, callback,
);
return true;
}
}
module.exports = Groups;