Adjust code to airbnb style guide, including eslint rules and prettier configuration for code base
This commit is contained in:
parent
1b55cabf63
commit
281acd6ad8
23 changed files with 919 additions and 2225 deletions
177
plejd/MqttClient.js
Normal file
177
plejd/MqttClient.js
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
const EventEmitter = require('events');
|
||||
const mqtt = require('mqtt');
|
||||
const Logger = require('./Logger');
|
||||
|
||||
const startTopic = 'hass/status';
|
||||
|
||||
const logger = Logger.getLogger('plejd-mqtt');
|
||||
|
||||
// #region discovery
|
||||
|
||||
const discoveryPrefix = 'homeassistant';
|
||||
const nodeId = 'plejd';
|
||||
|
||||
const getSubscribePath = () => `${discoveryPrefix}/+/${nodeId}/#`;
|
||||
const getPath = ({ id, type }) => `${discoveryPrefix}/${type}/${nodeId}/${id}`;
|
||||
const getConfigPath = (plug) => `${getPath(plug)}/config`;
|
||||
const getStateTopic = (plug) => `${getPath(plug)}/state`;
|
||||
const getCommandTopic = (plug) => `${getPath(plug)}/set`;
|
||||
const getSceneEventTopic = () => 'plejd/event/scene';
|
||||
|
||||
const getDiscoveryPayload = (device) => ({
|
||||
schema: 'json',
|
||||
name: device.name,
|
||||
unique_id: `light.plejd.${device.name.toLowerCase().replace(/ /g, '')}`,
|
||||
state_topic: getStateTopic(device),
|
||||
command_topic: getCommandTopic(device),
|
||||
optimistic: false,
|
||||
brightness: `${device.dimmable}`,
|
||||
device: {
|
||||
identifiers: `${device.serialNumber}_${device.id}`,
|
||||
manufacturer: 'Plejd',
|
||||
model: device.typeName,
|
||||
name: device.name,
|
||||
sw_version: device.version,
|
||||
},
|
||||
});
|
||||
|
||||
const getSwitchPayload = (device) => ({
|
||||
name: device.name,
|
||||
state_topic: getStateTopic(device),
|
||||
command_topic: getCommandTopic(device),
|
||||
optimistic: false,
|
||||
device: {
|
||||
identifiers: `${device.serialNumber}_${device.id}`,
|
||||
manufacturer: 'Plejd',
|
||||
model: device.typeName,
|
||||
name: device.name,
|
||||
sw_version: device.version,
|
||||
},
|
||||
});
|
||||
|
||||
// #endregion
|
||||
|
||||
class MqttClient extends EventEmitter {
|
||||
constructor(mqttBroker, username, password) {
|
||||
super();
|
||||
|
||||
this.mqttBroker = mqttBroker;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.deviceMap = {};
|
||||
this.devices = [];
|
||||
}
|
||||
|
||||
init() {
|
||||
logger.info('Initializing MQTT connection for Plejd addon');
|
||||
const self = this;
|
||||
|
||||
this.client = mqtt.connect(this.mqttBroker, {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
});
|
||||
|
||||
this.client.on('connect', () => {
|
||||
logger.info('Connected to MQTT.');
|
||||
|
||||
this.client.subscribe(startTopic, (err) => {
|
||||
if (err) {
|
||||
logger.error(`Unable to subscribe to ${startTopic}`);
|
||||
}
|
||||
|
||||
self.emit('connected');
|
||||
});
|
||||
|
||||
this.client.subscribe(getSubscribePath(), (err) => {
|
||||
if (err) {
|
||||
logger.error('Unable to subscribe to control topics');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.client.on('close', () => {
|
||||
logger.verbose('Warning: mqtt channel closed event, reconnecting...');
|
||||
self.reconnect();
|
||||
});
|
||||
|
||||
this.client.on('message', (topic, message) => {
|
||||
// const command = message.toString();
|
||||
const command = message.toString().substring(0, 1) === '{'
|
||||
? JSON.parse(message.toString())
|
||||
: message.toString();
|
||||
|
||||
if (topic === startTopic) {
|
||||
logger.info('Home Assistant has started. lets do discovery.');
|
||||
self.emit('connected');
|
||||
} else if (topic.includes('set')) {
|
||||
logger.verbose(`Got mqtt command on ${topic} - ${message}`);
|
||||
const device = self.devices.find((x) => getCommandTopic(x) === topic);
|
||||
self.emit('stateChanged', device, command);
|
||||
} else {
|
||||
logger.verbose(`Warning: Got unrecognized mqtt command on ${topic} - ${message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
this.client.reconnect();
|
||||
}
|
||||
|
||||
discover(devices) {
|
||||
this.devices = devices;
|
||||
|
||||
const self = this;
|
||||
logger.debug(`Sending discovery of ${devices.length} device(s).`);
|
||||
|
||||
devices.forEach((device) => {
|
||||
logger.debug(`Sending discovery for ${device.name}`);
|
||||
|
||||
const payload = device.type === 'switch' ? getSwitchPayload(device) : getDiscoveryPayload(device);
|
||||
logger.info(
|
||||
`Discovered ${device.type} (${device.typeName}) named ${device.name} with PID ${device.id}.`,
|
||||
);
|
||||
|
||||
self.deviceMap[device.id] = payload.unique_id;
|
||||
|
||||
self.client.publish(getConfigPath(device), JSON.stringify(payload));
|
||||
});
|
||||
}
|
||||
|
||||
updateState(deviceId, data) {
|
||||
const device = this.devices.find((x) => x.id === deviceId);
|
||||
|
||||
if (!device) {
|
||||
logger.warn(`Unknown device id ${deviceId} - not handled by us.`);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.verbose(`Updating state for ${device.name}: ${data.state}`);
|
||||
let payload = null;
|
||||
|
||||
if (device.type === 'switch') {
|
||||
payload = data.state === 1 ? 'ON' : 'OFF';
|
||||
} else {
|
||||
if (device.dimmable) {
|
||||
payload = {
|
||||
state: data.state === 1 ? 'ON' : 'OFF',
|
||||
brightness: data.brightness,
|
||||
};
|
||||
} else {
|
||||
payload = {
|
||||
state: data.state === 1 ? 'ON' : 'OFF',
|
||||
};
|
||||
}
|
||||
|
||||
payload = JSON.stringify(payload);
|
||||
}
|
||||
|
||||
this.client.publish(getStateTopic(device), payload);
|
||||
}
|
||||
|
||||
sceneTriggered(scene) {
|
||||
logger.verbose(`Scene triggered: ${scene}`);
|
||||
this.client.publish(getSceneEventTopic(), JSON.stringify({ scene }));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MqttClient;
|
||||
Loading…
Add table
Add a link
Reference in a new issue