diff --git a/lib/util/utils.js b/lib/util/utils.js index c2f812eea..68a639299 100644 --- a/lib/util/utils.js +++ b/lib/util/utils.js @@ -68,6 +68,9 @@ function getEndpointByEntityID(zigbee, entityID, epName) { logger.error(`Device ${mappedDevice.model} doesn't have ep named '${epName}'`); return; } + } else if (mappedDevice.hasOwnProperty('ep')) { + const eps = mappedDevice.ep(device); + epID = eps[''] || null; } const endpoint = zigbee.getEndpoint(entityID, epID); diff --git a/test/deviceBind.test.js b/test/deviceBind.test.js index ab2cf7a8b..67dab763e 100644 --- a/test/deviceBind.test.js +++ b/test/deviceBind.test.js @@ -28,6 +28,11 @@ const devices = { return {inClusterList: [5, 6]}; }, }, + occupancy_sensor: { + getSimpleDesc: () => { + return {outClusterList: [5, 6]}; + }, + }, }; const zigbee = { @@ -46,12 +51,15 @@ const zigbee = { return devices.switch_ep2; } else if (ep == 3 && ID === 'switch_ep3') { return devices.switch_ep3; + } else if (ep == 2 && ID == 'occupancy_sensor') { + return devices.occupancy_sensor; } throw new Error(`No mock for ${ID} and ep ${ep}`); }, getDevice: (ID) => { const lookup = { + 'occupancy_sensor': 'SML002', 'switch_ep2': 'lumi.sensor_86sw2.es1', 'switch_ep3': 'DNCKAT_S003', 'bulb': 'TRADFRI bulb E27 WS opal 980lm', @@ -154,6 +162,17 @@ describe('DeviceBind', () => { expect.any(Function) ); }); + + it('Bind default ep when mapped', async () => { + deviceBind.onMQTTMessage('zigbee2mqtt/bridge/bind/occupancy_sensor', 'bulb'); + expect(zigbee.bind).toHaveBeenCalledTimes(1); + expect(zigbee.bind).toHaveBeenNthCalledWith(1, + devices.occupancy_sensor, + 6, + devices.bulb, + expect.any(Function) + ); + }); }); describe('Unbind devices', () => { diff --git a/test/utils.test.js b/test/utils.test.js index 981a6c229..0c2c0240f 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -34,4 +34,45 @@ describe('Utils', () => { expect('EndDevice').toBe(utils.correctDeviceType(device)); }); }); + + describe('Get endpoint by id', () => { + it('Pick default ep', () => { + const zigbee = { + getDevice: (entityID) => { + return {modelId: 'TRADFRI on/off switch'}; + }, + getEndpoint: (entityID, epId) => { + return {epId: epId == null ? 1 : 0}; + }, + }; + const endpoint = utils.getEndpointByEntityID(zigbee, '0x12345678', null); + expect(endpoint.epId).toBe(1); + }); + + it('Pick default ep from mapping when default defined', () => { + const zigbee = { + getDevice: (entityID) => { + return {modelId: 'SML002'}; + }, + getEndpoint: (entityID, epId) => { + return {epId}; + }, + }; + const endpoint = utils.getEndpointByEntityID(zigbee, '0x12345678', null); + expect(endpoint.epId).toBe(2); + }); + + it('Pick default ep from mapping when not defined', () => { + const zigbee = { + getDevice: (entityID) => { + return {modelId: 'lumi.sensor_86sw2.es1'}; + }, + getEndpoint: (entityID, epId) => { + return {epId: epId == null ? 1 : 0}; + }, + }; + const endpoint = utils.getEndpointByEntityID(zigbee, '0x12345678', null); + expect(endpoint.epId).toBe(1); + }); + }); });