2018-11-07 11:40:58 -07:00
|
|
|
const chai = require('chai');
|
|
|
|
const sinon = require('sinon');
|
|
|
|
const DevicePublish = require('../lib/extension/devicePublish');
|
|
|
|
const settings = require('../lib/util/settings');
|
2018-11-28 11:34:37 -07:00
|
|
|
const utils = require('./utils');
|
|
|
|
const sandbox = sinon.createSandbox();
|
2018-11-07 11:40:58 -07:00
|
|
|
|
|
|
|
const mqtt = {
|
|
|
|
subscribe: (topic) => {},
|
|
|
|
};
|
|
|
|
|
2018-11-26 09:47:44 -07:00
|
|
|
const zigbee = {
|
|
|
|
getDevice: null,
|
|
|
|
publish: sinon.spy(),
|
|
|
|
};
|
|
|
|
|
|
|
|
const cfg = {
|
|
|
|
default: {
|
|
|
|
manufSpec: 0,
|
|
|
|
disDefaultRsp: 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-11-07 11:40:58 -07:00
|
|
|
describe('DevicePublish', () => {
|
|
|
|
let devicePublish;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2018-11-28 11:34:37 -07:00
|
|
|
utils.stubLogger(sandbox);
|
2018-11-26 09:47:44 -07:00
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
});
|
|
|
|
|
2018-11-28 11:34:37 -07:00
|
|
|
afterEach(() => {
|
|
|
|
sandbox.restore();
|
|
|
|
});
|
|
|
|
|
2018-11-26 09:47:44 -07:00
|
|
|
describe('Parse topic', () => {
|
|
|
|
it('Should publish messages to zigbee devices', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({brightness: '200'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genLevelCtrl');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'moveToLevelWithOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {level: '200', transtime: 0});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[6], null);
|
|
|
|
});
|
|
|
|
|
2018-11-27 13:19:53 -07:00
|
|
|
it('Should publish messages to zigbee devices when brightness is in %', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({brightness: '92%'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genLevelCtrl');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'moveToLevelWithOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {level: '235', transtime: 0});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[6], null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should publish messages to zigbee devices with color_temp', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({color_temp: '222'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'lightingColorCtrl');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'moveToColorTemp');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {colortemp: '222', transtime: 0});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[6], null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should publish messages to zigbee devices with color_temp in %', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({color_temp: '100%'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'lightingColorCtrl');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'moveToColorTemp');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {colortemp: '500', transtime: 0});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[6], null);
|
|
|
|
});
|
|
|
|
|
2018-11-26 09:47:44 -07:00
|
|
|
it('Should publish messages to zigbee devices with non-default ep', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'lumi.ctrl_neutral1'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({state: 'OFF'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'off');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[6], 2);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should publish messages to zigbee devices with non-default ep and postfix', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'lumi.ctrl_neutral2'});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/right/set', JSON.stringify({state: 'OFF'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'off');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[6], 3);
|
|
|
|
});
|
2018-11-27 13:50:55 -07:00
|
|
|
|
|
|
|
it('Should publish messages to zigbee gledopto with [11,13]', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'GLEDOPTO', epList: [11, 13]});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({state: 'OFF'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'off');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[6], null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should publish messages to zigbee gledopto with [11,12,13]', () => {
|
|
|
|
zigbee.publish.resetHistory();
|
|
|
|
zigbee.getDevice = sinon.fake.returns({modelId: 'GLEDOPTO', epList: [11, 12, 13]});
|
|
|
|
devicePublish = new DevicePublish(zigbee, mqtt, null, null);
|
|
|
|
devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({state: 'OFF'}));
|
|
|
|
chai.assert.isTrue(zigbee.publish.calledOnce);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[0], '0x12345678');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[1], 'genOnOff');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[2], 'off');
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[3], 'functional');
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[4], {});
|
|
|
|
chai.assert.deepEqual(zigbee.publish.getCall(0).args[5], cfg.default);
|
|
|
|
chai.assert.strictEqual(zigbee.publish.getCall(0).args[6], 12);
|
|
|
|
});
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('Parse topic', () => {
|
|
|
|
it('Should handle non-valid topics', () => {
|
|
|
|
const topic = 'zigbee2mqtt1/my_device_id/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should handle non-valid topics', () => {
|
|
|
|
const topic = 'zigbee2mqtt1/my_device_id/sett';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should handle non-valid topics', () => {
|
|
|
|
const topic = 'zigbee2mqtt/my_device_id/write';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should handle non-valid topics', () => {
|
|
|
|
const topic = 'zigbee2mqtt/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should handle non-valid topics', () => {
|
|
|
|
const topic = 'set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/my_device_id/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'my_device_id');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse get topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/my_device_id2/get';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'get');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'my_device_id2');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse topic with when base topic has multiple slashes', () => {
|
2018-11-28 11:34:37 -07:00
|
|
|
sandbox.stub(settings, 'get').callsFake(() => {
|
2018-11-07 11:40:58 -07:00
|
|
|
return {
|
|
|
|
mqtt: {
|
|
|
|
base_topic: 'zigbee2mqtt/at/my/home',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
const topic = 'zigbee2mqtt/at/my/home/my_device_id2/get';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'get');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'my_device_id2');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse topic with when deviceID has multiple slashes', () => {
|
|
|
|
const topic = 'zigbee2mqtt/floor0/basement/my_device_id2/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'floor0/basement/my_device_id2');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse topic with when base and deviceID have multiple slashes', () => {
|
2018-11-28 11:34:37 -07:00
|
|
|
sandbox.stub(settings, 'get').callsFake(() => {
|
2018-11-07 11:40:58 -07:00
|
|
|
return {
|
|
|
|
mqtt: {
|
|
|
|
base_topic: 'zigbee2mqtt/at/my/basement',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
const topic = 'zigbee2mqtt/at/my/basement/floor0/basement/my_device_id2/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'floor0/basement/my_device_id2');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set with ieeAddr topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/0x12345689/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, '0x12345689');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set with postfix topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/0x12345689/left/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, '0x12345689');
|
|
|
|
chai.assert.strictEqual(parsed.postfix, 'left');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set with postfix topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/0x12345689/right/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, '0x12345689');
|
|
|
|
chai.assert.strictEqual(parsed.postfix, 'right');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set with postfix topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/0x12345689/bottom_left/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, '0x12345689');
|
|
|
|
chai.assert.strictEqual(parsed.postfix, 'bottom_left');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Shouldnt parse set with invalid postfix topic', () => {
|
|
|
|
const topic = 'zigbee2mqtt/0x12345689/invalid/set';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'set');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, '0x12345689/invalid');
|
2018-11-19 12:29:35 -07:00
|
|
|
chai.assert.strictEqual(parsed.postfix, '');
|
2018-11-07 11:40:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Should parse set with and slashes in base and deviceID postfix topic', () => {
|
2018-11-28 11:34:37 -07:00
|
|
|
sandbox.stub(settings, 'get').callsFake(() => {
|
2018-11-07 11:40:58 -07:00
|
|
|
return {
|
|
|
|
mqtt: {
|
|
|
|
base_topic: 'zigbee2mqtt/at/my/home',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
const topic = 'zigbee2mqtt/at/my/home/my/device/in/basement/sensor/bottom_left/get';
|
|
|
|
const parsed = devicePublish.parseTopic(topic);
|
|
|
|
chai.assert.strictEqual(parsed.type, 'get');
|
|
|
|
chai.assert.strictEqual(parsed.deviceID, 'my/device/in/basement/sensor');
|
|
|
|
chai.assert.strictEqual(parsed.postfix, 'bottom_left');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|