2018-12-21 16:07:53 -07:00
|
|
|
const settings = require('../util/settings');
|
|
|
|
const logger = require('../util/logger');
|
|
|
|
|
2018-12-27 10:43:34 -07:00
|
|
|
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/.+/(remove|add|remove_all)$`);
|
2018-12-21 16:07:53 -07:00
|
|
|
|
|
|
|
class Groups {
|
|
|
|
constructor(zigbee, mqtt, state, publishDeviceState) {
|
|
|
|
this.zigbee = zigbee;
|
|
|
|
this.mqtt = mqtt;
|
|
|
|
this.state = state;
|
|
|
|
this.publishDeviceState = publishDeviceState;
|
|
|
|
}
|
|
|
|
|
|
|
|
onMQTTConnected() {
|
2018-12-27 10:43:34 -07:00
|
|
|
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`);
|
2018-12-21 16:07:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
parseTopic(topic) {
|
|
|
|
if (!topic.match(topicRegex)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove base from topic
|
2018-12-27 10:43:34 -07:00
|
|
|
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/group/`, '');
|
2018-12-21 16:07:53 -07:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
2018-12-27 10:43:34 -07:00
|
|
|
let cmd = null;
|
2018-12-21 16:07:53 -07:00
|
|
|
if (topic.type === 'add') {
|
2018-12-23 16:39:58 -07:00
|
|
|
payload = {groupid: groupID, groupname: ''};
|
2018-12-27 10:43:34 -07:00
|
|
|
cmd = 'add';
|
2018-12-21 16:07:53 -07:00
|
|
|
} else if (topic.type === 'remove') {
|
|
|
|
payload = {groupid: groupID};
|
2018-12-27 10:43:34 -07:00
|
|
|
cmd = 'remove';
|
|
|
|
} else if (topic.type === 'remove_all') {
|
|
|
|
payload = {};
|
|
|
|
cmd = 'removeAll';
|
2018-12-21 16:07:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
const callback = (error, rsp) => {
|
|
|
|
if (error) {
|
|
|
|
logger.error(`Failed to ${topic.type} ${ieeeAddr} from ${topic.friendly_name}`);
|
|
|
|
} else {
|
2018-12-21 16:15:33 -07:00
|
|
|
logger.info(`Successfully ${topic.type} ${ieeeAddr} to ${topic.friendly_name}`);
|
2018-12-21 16:07:53 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.zigbee.publish(
|
2018-12-27 10:43:34 -07:00
|
|
|
ieeeAddr, 'device', 'genGroups', cmd, 'functional',
|
2018-12-21 16:07:53 -07:00
|
|
|
payload, null, null, callback,
|
|
|
|
);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Groups;
|