From 7d25b842f2a29c2f757a004b44adb5c1bbdbf18e Mon Sep 17 00:00:00 2001 From: renzhe Date: Wed, 30 Oct 2024 09:46:48 +0800 Subject: [PATCH 1/5] Added Zigbee to RS485 controller support --- src/devices/easyiot.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/devices/easyiot.ts b/src/devices/easyiot.ts index 9914ebe06a01f..5a5e57eaa2ed0 100644 --- a/src/devices/easyiot.ts +++ b/src/devices/easyiot.ts @@ -30,6 +30,7 @@ const fzLocal = { return {last_received_status: hexString}; }, } satisfies Fz.Converter, + easyiot_sp1000_recv_status: { cluster: 'tunneling', type: ['commandTransferDataResp'], @@ -192,6 +193,18 @@ const definitions: DefinitionWithExtend[] = [ e.text('last_received_status', ea.STATE).withDescription('status'), ], }, + { + fingerprint: [{modelID: 'ZB-RS485', manufacturerName: 'easyiot'}], + model: 'RS485', + vendor: 'easyiot', + description: 'Zigbee to RS485 controller', + fromZigbee: [fzLocal.easyiot_ir_recv_command], + toZigbee: [tzLocal.easyiot_ir_send_command], + exposes: [ + e.text('last_received_command', ea.STATE).withDescription('Received data'), + e.text('send_command', ea.SET).withDescription('Send data'), + ], + }, ]; export default definitions; From 5204147c02b34a993e95c6132f41d7280b25f975 Mon Sep 17 00:00:00 2001 From: renzhe Date: Wed, 30 Oct 2024 10:47:22 +0800 Subject: [PATCH 2/5] add support ZB-PM01 --- src/devices/easyiot.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/devices/easyiot.ts b/src/devices/easyiot.ts index 5a5e57eaa2ed0..057b4d8414175 100644 --- a/src/devices/easyiot.ts +++ b/src/devices/easyiot.ts @@ -2,6 +2,7 @@ import * as iconv from 'iconv-lite'; import * as exposes from '../lib/exposes'; import {logger} from '../lib/logger'; +import {electricityMeter, onOff} from '../lib/modernExtend'; import {DefinitionWithExtend, Fz, Tz} from '../lib/types'; const NS = 'zhc:easyiot'; @@ -205,6 +206,13 @@ const definitions: DefinitionWithExtend[] = [ e.text('send_command', ea.SET).withDescription('Send data'), ], }, + { + zigbeeModel: ['ZB-PM01'], + model: 'ZB-PM01', + vendor: 'easyiot', + description: 'Smart circuit breaker with Metering', + extend: [onOff({powerOnBehavior: false}), electricityMeter()], + }, ]; export default definitions; From a3e3c1eeccf5d5744d7825a4dc7a35c046dd239e Mon Sep 17 00:00:00 2001 From: renzhe Date: Wed, 30 Oct 2024 11:20:59 +0800 Subject: [PATCH 3/5] support ZB-WC01 --- src/devices/easyiot.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/devices/easyiot.ts b/src/devices/easyiot.ts index 057b4d8414175..a53ce8935581b 100644 --- a/src/devices/easyiot.ts +++ b/src/devices/easyiot.ts @@ -2,7 +2,7 @@ import * as iconv from 'iconv-lite'; import * as exposes from '../lib/exposes'; import {logger} from '../lib/logger'; -import {electricityMeter, onOff} from '../lib/modernExtend'; +import {commandsWindowCovering, electricityMeter, onOff, windowCovering} from '../lib/modernExtend'; import {DefinitionWithExtend, Fz, Tz} from '../lib/types'; const NS = 'zhc:easyiot'; @@ -213,6 +213,13 @@ const definitions: DefinitionWithExtend[] = [ description: 'Smart circuit breaker with Metering', extend: [onOff({powerOnBehavior: false}), electricityMeter()], }, + { + zigbeeModel: ['ZB-WC01'], + model: 'ZB-WC01', + vendor: 'easyiot', + description: 'Curtain motor', + extend: [windowCovering({controls: ['lift']}), commandsWindowCovering()], + }, ]; export default definitions; From 4399429e2c98a2f5061ac3705f30e32c96a35fa1 Mon Sep 17 00:00:00 2001 From: renzhe Date: Wed, 30 Oct 2024 15:53:43 +0800 Subject: [PATCH 4/5] support ZB-WB01,ZB-WB02,ZB-WB03,ZB-WB08 --- src/devices/easyiot.ts | 122 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/src/devices/easyiot.ts b/src/devices/easyiot.ts index a53ce8935581b..691028d9e7c7e 100644 --- a/src/devices/easyiot.ts +++ b/src/devices/easyiot.ts @@ -2,8 +2,9 @@ import * as iconv from 'iconv-lite'; import * as exposes from '../lib/exposes'; import {logger} from '../lib/logger'; -import {commandsWindowCovering, electricityMeter, onOff, windowCovering} from '../lib/modernExtend'; -import {DefinitionWithExtend, Fz, Tz} from '../lib/types'; +import {electricityMeter, onOff, windowCovering} from '../lib/modernExtend'; +import * as reporting from '../lib/reporting'; +import {DefinitionWithExtend, Fz, KeyValueAny, Tz} from '../lib/types'; const NS = 'zhc:easyiot'; const ea = exposes.access; @@ -45,6 +46,27 @@ const fzLocal = { } }, } satisfies Fz.Converter, + + easyiot_action: { + cluster: 'genOnOff', + type: ['commandOn', 'commandOff', 'commandToggle'], + convert: (model, msg, publish, options, meta) => { + const lookup: KeyValueAny = {commandToggle: 'single', commandOn: 'double', commandOff: 'long'}; + let buttonMapping: KeyValueAny = null; + if (model.model === 'ZB-SW01') { + buttonMapping = {1: '1'}; + } else if (model.model === 'ZB-WB02') { + buttonMapping = {1: '1', 2: '2'}; + } else if (model.model === 'ZB-WB03') { + buttonMapping = {1: '1', 2: '2', 3: '3'}; + } else if (model.model === 'ZB-WB08') { + buttonMapping = {1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8'}; + } + + const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : ''; + return {action: `${button}${lookup[msg.type]}`}; + }, + } satisfies Fz.Converter, }; const tzLocal = { @@ -218,7 +240,101 @@ const definitions: DefinitionWithExtend[] = [ model: 'ZB-WC01', vendor: 'easyiot', description: 'Curtain motor', - extend: [windowCovering({controls: ['lift']}), commandsWindowCovering()], + extend: [windowCovering({controls: ['lift'], configureReporting: false})], + }, + { + zigbeeModel: ['ZB-WB01'], + model: 'ZB-WB01', + vendor: 'easyiot', + description: '1-button remote control', + fromZigbee: [fzLocal.easyiot_action], + toZigbee: [], + exposes: [e.action(['1_single', '1_double', '1_long']), e.battery()], + configure: async (device, coordinatorEndpoint) => { + const endpoint = device.getEndpoint(1); + await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']); + await reporting.batteryPercentageRemaining(endpoint, {min: 30, max: 1800, change: 1}); + }, + }, + { + zigbeeModel: ['ZB-WB02'], + model: 'ZB-WB02', + vendor: 'easyiot', + description: '2-button remote control', + fromZigbee: [fzLocal.easyiot_action], + toZigbee: [], + exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long']), e.battery()], + configure: async (device, coordinatorEndpoint) => { + const endpoint = device.getEndpoint(1); + await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']); + await reporting.batteryPercentageRemaining(endpoint, {min: 30, max: 1800, change: 1}); + await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']); + }, + }, + { + zigbeeModel: ['ZB-WB03'], + model: 'ZB-WB03', + vendor: 'easyiot', + description: '3-button remote control', + fromZigbee: [fzLocal.easyiot_action], + toZigbee: [], + exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long', '3_single', '3_double', '3_long']), e.battery()], + configure: async (device, coordinatorEndpoint) => { + const endpoint = device.getEndpoint(1); + await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']); + await reporting.batteryPercentageRemaining(endpoint, {min: 30, max: 1800, change: 1}); + await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']); + }, + }, + { + zigbeeModel: ['ZB-WB08'], + model: 'ZB-WB08', + vendor: 'easyiot', + description: '8-button remote control', + fromZigbee: [fzLocal.easyiot_action], + toZigbee: [], + exposes: [ + e.action([ + '1_single', + '1_double', + '1_long', + '2_single', + '2_double', + '2_long', + '3_single', + '3_double', + '3_long', + '4_single', + '4_double', + '4_long', + '5_single', + '5_double', + '5_long', + '6_single', + '6_double', + '6_long', + '7_single', + '7_double', + '7_long', + '8_single', + '8_double', + '8_long', + ]), + e.battery(), + ], + configure: async (device, coordinatorEndpoint) => { + const endpoint = device.getEndpoint(1); + await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']); + await reporting.batteryPercentageRemaining(endpoint, {min: 30, max: 1800, change: 1}); + await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(4), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(5), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(6), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(7), coordinatorEndpoint, ['genOnOff']); + await reporting.bind(device.getEndpoint(8), coordinatorEndpoint, ['genOnOff']); + }, }, ]; From e5bef7f649d0a051e9c9d34f7bdf46676b023438 Mon Sep 17 00:00:00 2001 From: renzhe Date: Wed, 30 Oct 2024 17:40:09 +0800 Subject: [PATCH 5/5] support ZB-SW08,ZB-PSW04 --- src/devices/easyiot.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/devices/easyiot.ts b/src/devices/easyiot.ts index 691028d9e7c7e..edeb70d1d156e 100644 --- a/src/devices/easyiot.ts +++ b/src/devices/easyiot.ts @@ -2,7 +2,7 @@ import * as iconv from 'iconv-lite'; import * as exposes from '../lib/exposes'; import {logger} from '../lib/logger'; -import {electricityMeter, onOff, windowCovering} from '../lib/modernExtend'; +import {deviceEndpoints, electricityMeter, onOff, windowCovering} from '../lib/modernExtend'; import * as reporting from '../lib/reporting'; import {DefinitionWithExtend, Fz, KeyValueAny, Tz} from '../lib/types'; @@ -336,6 +336,26 @@ const definitions: DefinitionWithExtend[] = [ await reporting.bind(device.getEndpoint(8), coordinatorEndpoint, ['genOnOff']); }, }, + { + fingerprint: [{modelID: 'ZB-PSW04', manufacturerName: 'easyiot'}], + model: 'ZB-PSW04', + vendor: 'easyiot', + description: 'Zigbee 4-channel relay', + extend: [ + deviceEndpoints({endpoints: {l1: 1, l2: 2, l3: 3, l4: 4}}), + onOff({endpointNames: ['l1', 'l2', 'l3', 'l4'], configureReporting: false, powerOnBehavior: false}), + ], + }, + { + fingerprint: [{modelID: 'ZB-SW08', manufacturerName: 'easyiot'}], + model: 'ZB-SW08', + vendor: 'easyiot', + description: 'Zigbee 8-channel relay', + extend: [ + deviceEndpoints({endpoints: {l1: 1, l2: 2, l3: 3, l4: 4, l5: 5, l6: 6, l7: 7, l8: 8}}), + onOff({endpointNames: ['l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8'], configureReporting: false, powerOnBehavior: false}), + ], + }, ]; export default definitions;