2018-04-08 05:46:20 -07:00
|
|
|
const debug = require('debug')('xiaomi-zb2mqtt')
|
|
|
|
const util = require("util");
|
|
|
|
const perfy = require('perfy');
|
|
|
|
const ZShepherd = require('zigbee-shepherd');
|
|
|
|
const mqtt = require('mqtt')
|
2018-04-08 08:25:28 -07:00
|
|
|
const fs = require('fs');
|
2018-04-09 08:09:52 -07:00
|
|
|
const parsers = require('./parsers');
|
2018-04-09 08:37:21 -07:00
|
|
|
const config = require('yaml-config');
|
|
|
|
const configFile = `${__dirname}/data/configuration.yaml`
|
|
|
|
const settings = config.readConfig(configFile, 'user');
|
|
|
|
|
|
|
|
// Create empty device array if not set yet.
|
|
|
|
if (!settings.devices) {
|
|
|
|
settings.devices = {};
|
|
|
|
writeConfig();
|
2018-04-08 08:25:28 -07:00
|
|
|
}
|
|
|
|
|
2018-04-08 05:46:20 -07:00
|
|
|
// Setup client
|
2018-04-09 08:37:21 -07:00
|
|
|
console.log(`Connecting to MQTT server at ${settings.mqtt.server}`)
|
|
|
|
const client = mqtt.connect(settings.mqtt.server)
|
2018-04-08 07:41:42 -07:00
|
|
|
const shepherd = new ZShepherd(
|
2018-04-09 08:37:21 -07:00
|
|
|
settings.serial.port,
|
2018-04-08 07:41:42 -07:00
|
|
|
{
|
|
|
|
net: {panId: 0x1a62},
|
|
|
|
dbPath: `${__dirname}/data/database.db`
|
|
|
|
}
|
|
|
|
);
|
2017-09-27 09:39:10 -07:00
|
|
|
|
2018-04-08 06:00:36 -07:00
|
|
|
// Register callbacks
|
|
|
|
client.on('connect', handleConnect);
|
2018-04-08 07:16:36 -07:00
|
|
|
shepherd.on('ready', handleReady);
|
|
|
|
shepherd.on('ind', handleMessage);
|
2018-04-08 06:33:47 -07:00
|
|
|
process.on('SIGINT', handleQuit);
|
2018-04-08 06:00:36 -07:00
|
|
|
|
|
|
|
// Start server
|
2018-04-09 08:37:21 -07:00
|
|
|
console.log(`Starting zigbee-shepherd with device ${settings.serial.port}`)
|
2018-04-08 06:00:36 -07:00
|
|
|
shepherd.start((err) => {
|
|
|
|
if (err) {
|
2018-04-08 06:28:59 -07:00
|
|
|
console.error('Error while starting zigbee-shepherd');
|
2018-04-08 06:00:36 -07:00
|
|
|
console.error(err);
|
2018-04-08 06:28:59 -07:00
|
|
|
} else {
|
|
|
|
console.error('zigbee-shepherd started');
|
2018-04-08 06:00:36 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Callbacks
|
|
|
|
function handleReady() {
|
2018-04-08 06:51:33 -07:00
|
|
|
console.log('zigbee-shepherd ready');
|
2018-04-08 07:16:36 -07:00
|
|
|
|
|
|
|
const devices = shepherd.list().filter((device) => {
|
|
|
|
return device.manufId === 4151 && device.type === 'EndDevice'
|
|
|
|
});
|
|
|
|
|
|
|
|
console.log(`Currently ${devices.length} devices are joined:`);
|
|
|
|
devices.forEach((device) => {
|
2018-04-09 08:09:52 -07:00
|
|
|
console.log(`${device.ieeeAddr} ${device.nwkAddr} ${device.modelId}`);
|
2018-04-08 07:16:36 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
// Set all Xiaomi devices to be online, so shepherd won't try
|
|
|
|
// to query info from devices (which would fail because they go tosleep).
|
|
|
|
devices.forEach((device) => {
|
|
|
|
shepherd.find(device.ieeeAddr, 1).getDevice().update({
|
|
|
|
status: 'online',
|
|
|
|
joinTime: Math.floor(Date.now()/1000)
|
|
|
|
});
|
2017-12-24 13:41:01 -07:00
|
|
|
});
|
2018-04-08 06:51:33 -07:00
|
|
|
|
|
|
|
// Allow or disallow new devices to join the network.
|
2018-04-09 08:45:02 -07:00
|
|
|
if (settings.allowJoin) {
|
|
|
|
console.log(`
|
|
|
|
WARNING: allowJoin set to true in configuration.yaml.
|
|
|
|
Allowing new devices to join.
|
|
|
|
Remove this parameter once you joined all devices.
|
|
|
|
`);
|
2018-04-08 06:51:33 -07:00
|
|
|
}
|
2018-04-08 07:16:36 -07:00
|
|
|
|
2018-04-09 08:45:02 -07:00
|
|
|
shepherd.permitJoin(settings.allowJoin ? 255 : 0, (err) => {
|
2018-04-08 06:51:33 -07:00
|
|
|
if (err) {
|
2017-09-27 09:39:10 -07:00
|
|
|
console.log(err);
|
2018-04-08 06:51:33 -07:00
|
|
|
}
|
2017-09-27 14:56:21 -07:00
|
|
|
});
|
2018-04-08 06:00:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
function handleConnect() {
|
|
|
|
client.publish('xiaomiZb', 'Bridge online');
|
|
|
|
}
|
|
|
|
|
2018-04-08 07:16:36 -07:00
|
|
|
function handleMessage(msg) {
|
2018-04-09 08:09:52 -07:00
|
|
|
if (msg.type !== 'attReport') {
|
|
|
|
return;
|
2017-09-27 09:39:10 -07:00
|
|
|
}
|
|
|
|
|
2018-04-09 08:09:52 -07:00
|
|
|
const device = msg.endpoints[0].device;
|
|
|
|
|
|
|
|
// Check if new device, add to config if new.
|
2018-04-09 08:37:21 -07:00
|
|
|
if (!settings.devices[device.ieeeAddr]) {
|
2018-04-09 08:09:52 -07:00
|
|
|
console.log(`Detected new device: ${device.ieeeAddr} ${device.nwkAddr} ${device.modelId}`);
|
2018-04-09 08:37:21 -07:00
|
|
|
|
|
|
|
settings.devices[device.ieeeAddr] = {
|
|
|
|
friendly_name: device.ieeeAddr
|
|
|
|
};
|
|
|
|
writeConfig();
|
2017-09-27 14:56:21 -07:00
|
|
|
}
|
2018-04-09 08:09:52 -07:00
|
|
|
|
|
|
|
// Check if we have a parser for this type of message.
|
|
|
|
const deviceID = msg.endpoints[0].devId;
|
|
|
|
const parser = parsers.find((p) => p.supportedDevices.includes(deviceID));
|
|
|
|
if (!parser) {
|
|
|
|
console.log(`
|
|
|
|
WARNING: No parser available for deviceID: ${deviceID}
|
|
|
|
Please report on https://github.com/Koenkk/xiaomi-zb2mqtt/issues
|
|
|
|
to add support for your device`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the message.
|
2018-04-09 08:37:21 -07:00
|
|
|
const friendlyName = settings.devices[device.ieeeAddr].friendly_name;
|
2018-04-09 08:09:52 -07:00
|
|
|
const payload = parser.parse(msg).toString();
|
2018-04-09 08:47:26 -07:00
|
|
|
const topic = `${settings.mqtt.base_topic}/${friendlyName}/${parser.topic}`;
|
2018-04-09 08:09:52 -07:00
|
|
|
|
|
|
|
// Send the message.
|
|
|
|
console.log(`MQTT publish, topic: '${topic}', payload: '${payload}'`);
|
|
|
|
client.publish(topic, payload);
|
2018-04-08 06:33:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
function handleQuit() {
|
|
|
|
shepherd.stop((err) => {
|
|
|
|
if (err) {
|
|
|
|
console.error('Error while stopping zigbee-shepherd');
|
|
|
|
} else {
|
|
|
|
console.error('zigbee-shepherd stopped')
|
|
|
|
}
|
|
|
|
|
|
|
|
process.exit();
|
|
|
|
});
|
|
|
|
}
|
2018-04-08 08:25:28 -07:00
|
|
|
|
|
|
|
|
2018-04-09 08:37:21 -07:00
|
|
|
function writeConfig() {
|
|
|
|
config.updateConfig(settings, configFile, 'user');
|
2018-04-08 08:25:28 -07:00
|
|
|
}
|