Skip to content

Instantly share code, notes, and snippets.

@komelgman
Created September 19, 2019 12:44
Show Gist options
  • Save komelgman/7eb16f8d3833cd8509e141d580a268db to your computer and use it in GitHub Desktop.
Save komelgman/7eb16f8d3833cd8509e141d580a268db to your computer and use it in GitHub Desktop.
Incoming message intercepting in extension
/* istanbul ignore file */
// todo (magic toggle)
const utils = require('../util/utils');
const interval = utils.secondsToMilliseconds(1);
const logger = require('../util/logger');
/**
* Extension required for Livolo device support.
*/
class Livolo {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.configured = {};
}
async onZigbeeStarted() {
(await this.zigbee.getClients())
.filter(Livolo.isLivolo)
.forEach((livoloDevice) => {
this._registerIncomingMsgProcessor(livoloDevice)
});
}
_registerIncomingMsgProcessor(livoloDevice) {
this.zigbee.herdsman.adapter
.registerIncomingMsgProcessor(livoloDevice.networkAddress, Livolo.incomingMessageProcessor.bind({
ext: this,
device: livoloDevice
}));
}
static isLivolo(device) {
return device.manufacturerName && device.manufacturerName.startsWith('LIVOLO')
&& device.type === 'EndDevice' && device.powerSource && device.powerSource !== 'Battery';
}
/**
* This callback change incomingMessage data and then message processed as usual
*/
static incomingMessagePreprocessor(object) {
const payload = object.payload;
if (payload.srcendpoint === 6 && payload.dstendpoint === 8 && payload.clusterid === 1) {
const malformedHeader = Buffer.from([0x7c, 0xd2, 0x15, 0xd8, 0x00]);
if (malformedHeader.compare(payload.data, 0, 4)) {
object.payload.data = Buffer.from([
0x18, 0xd8, 0x01, // header
0x00, 0x00, // attrId
0x00, // success
0x10, // boolean
object.payload.data[15]
]);
object.payload.clusterid = 6;
}
}
return false;
}
/**
* This callback handle incomingMessage and break default processing
*/
static incomingMessageProcessor(object) {
const payload = object.payload;
if (payload.srcendpoint === 6 && payload.dstendpoint === 8 && payload.clusterid === 1) {
const malformedHeader = Buffer.from([0x7c, 0xd2, 0x15, 0xd8, 0x00]);
if (malformedHeader.compare(payload.data, 0, 4)) {
const status = object.payload.data[15];
const state = {};
state['state_left'] = status & 1 ? 'ON' : 'OFF';
state['state_right'] = status & 2 ? 'ON' : 'OFF';
state['linkquality'] = payload.linkquality;
this.ext.publishEntityState(this.device.ieeeAddr, state);
}
}
return true;
}
}
module.exports = Livolo;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment