zigbee2mqtt/lib/mqtt.js

137 lines
4.2 KiB
JavaScript
Raw Normal View History

2018-04-18 09:25:40 -07:00
const mqtt = require('mqtt');
const logger = require('./util/logger');
const settings = require('./util/settings');
const fs = require('fs');
2018-04-18 09:25:40 -07:00
class MQTT {
constructor() {
2018-11-16 12:23:11 -07:00
this.onConnect = this.onConnect.bind(this);
this.onMessage = this.onMessage.bind(this);
this.messageHandler = null;
2018-04-18 09:25:40 -07:00
}
2018-11-16 12:23:11 -07:00
connect(messageHandler, callback) {
2018-04-18 09:25:40 -07:00
const mqttSettings = settings.get().mqtt;
logger.info(`Connecting to MQTT server at ${mqttSettings.server}`);
2018-08-09 09:23:04 -07:00
const options = {
will: {
2018-11-16 12:23:11 -07:00
topic: `${settings.get().mqtt.base_topic}/bridge/state`,
2018-08-09 09:23:04 -07:00
payload: 'offline',
retain: true,
},
};
if (mqttSettings.ca) {
logger.debug(`MQTT SSL/TLS: Path to CA certificate = ${mqttSettings.ca}`);
const ca = fs.readFileSync(mqttSettings.ca);
if (ca) {
options.ca = ca;
} else {
logger.error(`Error loading CA certificate for MQTT SSL/TLS configuration.`);
}
}
if (mqttSettings.key && mqttSettings.cert) {
logger.debug(`MQTT SSL/TLS: Path to client key = ${mqttSettings.key}`);
logger.debug(`MQTT SSL/TLS: Path to client certificate = ${mqttSettings.cert}`);
const key = fs.readFileSync(mqttSettings.key);
const cert = fs.readFileSync(mqttSettings.cert);
if (key && cert) {
options.key = key;
options.cert = cert;
} else {
logger.error(`Error loading key and/or certificate for MQTT SSL/TLS client authentication.`);
}
}
2018-04-18 09:25:40 -07:00
if (mqttSettings.user && mqttSettings.password) {
options.username = mqttSettings.user;
options.password = mqttSettings.password;
}
2018-06-26 10:33:26 -07:00
if (mqttSettings.client_id) {
logger.debug(`Using MQTT client ID: '${mqttSettings.client_id}'`);
options.clientId = mqttSettings.client_id;
}
if (mqttSettings.hasOwnProperty('reject_unauthorized') && !mqttSettings.reject_unauthorized) {
logger.debug(`MQTT reject_unauthorized set false, ignoring certificate warnings.`);
options.rejectUnauthorized = false;
}
2018-06-26 10:33:26 -07:00
2018-04-18 09:25:40 -07:00
this.client = mqtt.connect(mqttSettings.server, options);
// Register callbacks.
this.client.on('connect', () => {
2018-11-16 12:23:11 -07:00
this.onConnect();
callback();
});
2018-11-16 12:23:11 -07:00
this.client.on('message', this.onMessage);
2018-04-18 09:25:40 -07:00
// Set timer at interval to check if connected to MQTT server.
const interval = 10 * 1000; // seconds * 1000.
this.connectionTimer = setInterval(() => {
if (this.client.reconnecting) {
logger.error('Not connected to MQTT server!');
}
}, interval);
2018-11-16 12:23:11 -07:00
this.messageHandler = messageHandler;
2018-04-18 09:25:40 -07:00
}
disconnect() {
clearTimeout(this.connectionTimer);
this.connectionTimer = null;
this.publish('bridge/state', 'offline', {retain: true, qos: 0}, () => {
2018-04-18 11:53:22 -07:00
logger.info('Disconnecting from MQTT server');
this.client.end();
});
2018-04-18 09:25:40 -07:00
}
2018-11-16 12:23:11 -07:00
onConnect() {
2018-04-18 09:25:40 -07:00
logger.info('Connected to MQTT server');
this.publish('bridge/state', 'online', {retain: true, qos: 0});
}
subscribe(topic) {
this.client.subscribe(topic);
2018-04-18 09:25:40 -07:00
}
2018-11-16 12:23:11 -07:00
onMessage(topic, message) {
if (this.messageHandler) {
this.messageHandler(topic, message);
2018-04-18 09:25:40 -07:00
}
}
2018-11-16 12:23:11 -07:00
publish(topic, payload, options, callback, base=settings.get().mqtt.base_topic) {
topic = `${base}/${topic}`;
2018-04-18 09:25:40 -07:00
if (!this.client || this.client.reconnecting) {
logger.error(`Not connected to MQTT server!`);
logger.error(`Cannot send message: topic: '${topic}', payload: '${payload}`);
return;
}
2018-11-16 12:23:11 -07:00
logger.info(`MQTT publish: topic '${topic}', payload '${payload}'`);
this.client.publish(topic, payload, options, callback);
2018-04-18 09:25:40 -07:00
}
2018-05-30 09:09:24 -07:00
log(type, message, meta=null) {
const payload = {type, message};
if (meta) {
payload.meta = meta;
}
2018-05-30 09:09:24 -07:00
this.publish('bridge/log', JSON.stringify(payload), {retain: false});
}
2018-04-18 09:25:40 -07:00
}
module.exports = MQTT;