UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

964 lines 59.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const zigbee_herdsman_1 = require("zigbee-herdsman"); const fromZigbee_1 = __importDefault(require("../converters/fromZigbee")); const toZigbee_1 = __importDefault(require("../converters/toZigbee")); const exposes = __importStar(require("../lib/exposes")); const reporting = __importStar(require("../lib/reporting")); const constants = __importStar(require("../lib/constants")); const utils = __importStar(require("../lib/utils")); const ota = __importStar(require("../lib/ota")); const e = exposes.presets; const ea = exposes.access; const dataType = { boolean: 16, uint8: 32, uint16: 33, int8: 40, int16: 41, enum8: 48, charStr: 66, ieeeAddr: 240, }; const fzLocal = { ctm_mbd_device_enabled: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty('onOff')) { result.device_enabled = data['onOff'] ? 'ON' : 'OFF'; } return result; }, }, ctm_device_mode: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x2200)) { const deviceModeLookup = { 0: 'astro_clock', 1: 'timer', 2: 'daily_timer', 3: 'weekly_timer' }; result.device_mode = utils.getFromLookup(data[0x2200], deviceModeLookup); } return result; }, }, ctm_device_enabled: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x2201)) { result.device_enabled = data[0x2201] ? 'ON' : 'OFF'; } return result; }, }, ctm_child_lock: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x2202)) { result.child_lock = data[0x2202] ? 'locked' : 'unlocked'; } return result; }, }, ctm_current_flag: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x5000)) { result.current_flag = data[0x5000]; } return result; }, }, ctm_relay_state: { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x5001)) { result.state = data[0x5001] ? 'ON' : 'OFF'; } return result; }, }, ctm_thermostat: { cluster: 'hvacThermostat', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x0401)) { // Load result.load = data[0x0401]; } if (data.hasOwnProperty('elkoLoad')) { // Load result.load = data['elkoLoad']; } if (data.hasOwnProperty(0x0402)) { // Display text result.display_text = data[0x0402]; } if (data.hasOwnProperty('elkoDisplayText')) { // Display text result.display_text = data['elkoDisplayText']; } if (data.hasOwnProperty(0x0403)) { // Sensor const sensorModeLookup = { 0: 'air', 1: 'floor', 2: 'external', 3: 'regulator', 4: 'mv_air', 5: 'mv_external', 6: 'mv_regulator' }; result.sensor = utils.getFromLookup(data[0x0403], sensorModeLookup); } if (data.hasOwnProperty('elkoSensor')) { // Sensor const sensorModeLookup = { 0: 'air', 1: 'floor', 2: 'external', 3: 'regulator', 4: 'mv_air', 5: 'mv_external', 6: 'mv_regulator' }; result.sensor = utils.getFromLookup(data['elkoSensor'], sensorModeLookup); } if (data.hasOwnProperty(0x0405)) { // Regulator mode result.regulator_mode = data[0x0405] ? 'regulator' : 'thermostat'; } if (data.hasOwnProperty('elkoRegulatorMode')) { // Regulator mode result.regulator_mode = data['elkoRegulatorMode'] ? 'regulator' : 'thermostat'; } if (data.hasOwnProperty(0x0406)) { // Power status result.power_status = data[0x0406] ? 'ON' : 'OFF'; } if (data.hasOwnProperty('elkoPowerStatus')) { // Power status result.power_status = data['elkoPowerStatus'] ? 'ON' : 'OFF'; } if (data.hasOwnProperty(0x0408)) { // Mean power result.mean_power = data[0x0408]; } if (data.hasOwnProperty('elkoMeanPower')) { // Mean power result.mean_power = data['elkoMeanPower']; } if (data.hasOwnProperty(0x0409)) { // Floor temp result.floor_temp = utils.precisionRound(data[0x0409], 2) / 100; } if (data.hasOwnProperty('elkoExternalTemp')) { // External temp (floor) result.floor_temp = utils.precisionRound(data['elkoExternalTemp'], 2) / 100; } if (data.hasOwnProperty(0x0411)) { // Night switching result.night_switching = data[0x0411] ? 'ON' : 'OFF'; } if (data.hasOwnProperty('elkoNightSwitching')) { // Night switching result.night_switching = data['elkoNightSwitching'] ? 'ON' : 'OFF'; } if (data.hasOwnProperty(0x0412)) { // Frost guard result.frost_guard = data[0x0412] ? 'ON' : 'OFF'; } if (data.hasOwnProperty('elkoFrostGuard')) { // Frost guard result.frost_guard = data['elkoFrostGuard'] ? 'ON' : 'OFF'; } if (data.hasOwnProperty(0x0413)) { // Child lock result.child_lock = data[0x0413] ? 'LOCK' : 'UNLOCK'; } if (data.hasOwnProperty('elkoChildLock')) { // Child lock result.child_lock = data['elkoChildLock'] ? 'LOCK' : 'UNLOCK'; } if (data.hasOwnProperty(0x0414)) { // Max floor temp result.max_floor_temp = data[0x0414]; } if (data.hasOwnProperty('elkoMaxFloorTemp')) { // Max floor temp result.max_floor_temp = data['elkoMaxFloorTemp']; } if (data.hasOwnProperty(0x0415)) { // Running_state result.running_state = data[0x0415] ? 'heat' : 'idle'; } if (data.hasOwnProperty('elkoRelayState')) { // Running_state result.running_state = data['elkoRelayState'] ? 'heat' : 'idle'; } if (data.hasOwnProperty(0x0420)) { // Regulator setpoint result.regulator_setpoint = data[0x0420]; } if (data.hasOwnProperty(0x0421)) { // Regulation mode const regulationModeLookup = { 0: 'thermostat', 1: 'regulator', 2: 'zzilent' }; result.regulation_mode = utils.getFromLookup(data[0x0421], regulationModeLookup); } if (data.hasOwnProperty(0x0422)) { // Operation mode const presetLookup = { 0: 'off', 1: 'away', 2: 'sleep', 3: 'home' }; const systemModeLookup = { 0: 'off', 1: 'off', 2: 'off', 3: 'heat' }; result.preset = utils.getFromLookup(data[0x0422], presetLookup); result.system_mode = utils.getFromLookup(data[0x0422], systemModeLookup); } if (data.hasOwnProperty(0x0423)) { // Maximum floor temp guard result.max_floor_guard = data[0x0423] ? 'ON' : 'OFF'; } if (data.hasOwnProperty(0x0424)) { // Weekly timer enabled result.weekly_timer = data[0x0424] ? 'ON' : 'OFF'; } if (data.hasOwnProperty(0x0425)) { // Frost guard setpoint result.frost_guard_setpoint = data[0x0425]; } if (data.hasOwnProperty(0x0426)) { // External temperature result.external_temp = utils.precisionRound(data[0x0426], 2) / 100; } if (data.hasOwnProperty(0x0428)) { // External sensor source result.exteral_sensor_source = data[0x0428]; } if (data.hasOwnProperty(0x0429)) { // Current air temperature result.air_temp = utils.precisionRound(data[0x0429], 2) / 100; } if (data.hasOwnProperty(0x0424)) { // Floor Sensor Error result.floor_sensor_error = data[0x042B] ? 'error' : 'ok'; } if (data.hasOwnProperty(0x0424)) { // External Air Sensor Error result.exteral_sensor_error = data[0x042C] ? 'error' : 'ok'; } return result; }, }, ctm_group_config: { cluster: '65191', // 0xFEA7 ctmGroupConfig type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x0000)) { result.group_id = data[0x0000]; } return result; }, }, ctm_sove_guard: { cluster: '65481', // 0xFFC9 ctmSoveGuard type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const result = {}; const data = msg.data; if (data.hasOwnProperty(0x0001)) { // Alarm status const alarmStatusLookup = { 0: 'ok', 1: 'tamper', 2: 'high_temperatur', 3: 'timer', 4: 'battery_alarm', 5: 'error', 0xFF: 'unknown' }; result.alarm_status = utils.getFromLookup(data[0x0001], alarmStatusLookup); } if (data.hasOwnProperty(0x0002)) { // Change battery result.battery_low = data[0x0002] ? true : false; } if (data.hasOwnProperty(0x0003)) { // Stove temperature result.stove_temperature = data[0x0003]; } if (data.hasOwnProperty(0x0004)) { // Ambient temperature result.ambient_temperature = data[0x0004]; } if (data.hasOwnProperty(0x0005)) { // Active result.active = data[0x0005] ? true : false; } if (data.hasOwnProperty(0x0006)) { // Runtime result.runtime = data[0x0006]; } if (data.hasOwnProperty(0x0007)) { // Runtime timeout result.runtime_timeout = data[0x0007]; } if (data.hasOwnProperty(0x0008)) { // Reset reason const resetReasonLookup = { 0: 'unknown', 1: 'power_on', 2: 'external', 3: 'brown_out', 4: 'watchdog', 5: 'program_interface', 6: 'software', 0xFF: 'unknown' }; result.reset_reason = utils.getFromLookup(data[0x0008], resetReasonLookup); } if (data.hasOwnProperty(0x0009)) { // Dip switch result.dip_switch = data[0x0009]; } if (data.hasOwnProperty(0x000A)) { // Software version result.sw_version = data[0x000A]; } if (data.hasOwnProperty(0x000B)) { // Hardware version result.hw_version = data[0x000B]; } if (data.hasOwnProperty(0x000C)) { // Bootloader version result.bootloader_version = data[0x000C]; } if (data.hasOwnProperty(0x000D)) { // Model const modelLookup = { 0: 'unknown', 1: '1_8', 2: 'infinity', 3: 'hybrid', 4: 'tak', 0xFF: 'unknown' }; result.model = utils.getFromLookup(data[0x000D], modelLookup); } if (data.hasOwnProperty(0x0010)) { // Relay address result.relay_address = data[0x0010]; } if (data.hasOwnProperty(0x0100)) { // Relay current flag const currentFlagLookup = { 0: 'false', 1: 'true', 0xFF: 'unknown' }; result.current_flag = utils.getFromLookup(data[0x0100], currentFlagLookup); } if (data.hasOwnProperty(0x0101)) { // Relay current result.relay_current = data[0x0101]; } if (data.hasOwnProperty(0x0102)) { // Relay status const relayStatusLookup = { 0: 'off', 1: 'on', 2: 'not_present', 0xFF: 'unknown' }; result.relay_status = utils.getFromLookup(data[0x0102], relayStatusLookup); } if (data.hasOwnProperty(0x0103)) { // Relay external button const relayStatusLookup = { 0: 'not_clicked', 1: 'clicked', 0xFF: 'unknown' }; result.external_button = utils.getFromLookup(data[0x0103], relayStatusLookup); } if (data.hasOwnProperty(0x0104)) { // Relay alarm const relayAlarmLookup = { 0: 'ok', 1: 'no_communication', 2: 'over_current', 3: 'over_temperature', 0xFF: 'unknown' }; result.relay_alarm = utils.getFromLookup(data[0x0104], relayAlarmLookup); } if (data.hasOwnProperty(0x0105)) { // Alarm status (from relay) const relayAlarmStatusLookup = { 0: 'ok', 1: 'tamper', 2: 'high_temperatur', 3: 'timer', 4: 'battery_alarm', 5: 'error', 0xFF: 'unknown' }; result.relay_alarm_status = utils.getFromLookup(data[0x0105], relayAlarmStatusLookup); } return result; }, }, ctm_water_leak_alarm: { cluster: 'ssIasZone', type: ['commandStatusChangeNotification', 'attributeReport'], convert: (model, msg, publish, options, meta) => { const zoneStatus = msg.data.zonestatus; return { active_water_leak: (zoneStatus & 1) > 0, water_leak: (zoneStatus & 1 << 1) > 0, battery_low: (zoneStatus & 1 << 3) > 0, }; }, }, }; const tzLocal = { ctm_mbd_device_enabled: { key: ['device_enabled'], convertSet: async (entity, key, value, meta) => { utils.assertString(value, 'device_enabled'); await entity.command('genOnOff', value.toLowerCase(), {}, utils.getOptions(meta.mapped, entity)); }, convertGet: async (entity, key, meta) => { await entity.read('genOnOff', ['onOff']); }, }, ctm_mbd_brightness: { key: ['brightness'], convertSet: async (entity, key, value, meta) => { await entity.command('genLevelCtrl', 'moveToLevel', { level: value, transtime: 1 }, utils.getOptions(meta.mapped, entity)); }, convertGet: async (entity, key, meta) => { await entity.read('genLevelCtrl', ['currentLevel']); }, }, ctm_device_mode: { key: ['device_mode'], convertGet: async (entity, key, meta) => { await entity.read('genOnOff', [0x2200]); }, }, ctm_device_enabled: { key: ['device_enabled'], convertSet: async (entity, key, value, meta) => { await entity.write('genOnOff', { 0x2201: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); }, convertGet: async (entity, key, meta) => { await entity.read('genOnOff', [0x2201]); }, }, ctm_child_lock: { key: ['child_lock'], convertGet: async (entity, key, meta) => { await entity.read('genOnOff', [0x2202]); }, }, ctm_current_flag: { key: ['current_flag'], convertGet: async (entity, key, meta) => { await entity.read('genOnOff', [0x5000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, }, ctm_relay_state: { key: ['state'], convertSet: async (entity, key, value, meta) => { await entity.write('genOnOff', { 0x5001: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, convertGet: async (entity, key, meta) => { await entity.read('genOnOff', [0x5001], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, }, ctm_thermostat: { key: ['load', 'display_text', 'sensor', 'regulator_mode', 'power_status', 'system_mode', 'night_switching', 'frost_guard', 'max_floor_temp', 'regulator_setpoint', 'regulation_mode', 'max_floor_guard', 'weekly_timer', 'exteral_sensor_source', ], convertSet: async (entity, key, value, meta) => { switch (key) { case 'load': await entity.write('hvacThermostat', { 0x0401: { value: value, type: dataType.uint16 } }); break; case 'display_text': await entity.write('hvacThermostat', { 0x0402: { value: value, type: dataType.charStr } }); break; case 'sensor': await entity.write('hvacThermostat', { 0x0403: { value: utils.getFromLookup(value, { 'air': 0, 'floor': 1, 'external': 2, 'regulator': 3, 'mv_air': 4, 'mv_external': 5, 'mv_regulator': 6 }), type: dataType.enum8 } }); break; case 'regulator_mode': await entity.write('hvacThermostat', { 0x0405: { value: utils.getFromLookup(value, { 'thermostat': 0, 'regulator': 1 }), type: dataType.boolean } }); break; case 'power_status': await entity.write('hvacThermostat', { 0x0406: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); break; case 'system_mode': if (value === 'off') { await entity.write('hvacThermostat', { 0x0406: { value: 0, type: dataType.boolean } }); } else if (value === 'heat') { await entity.write('hvacThermostat', { 0x0422: { value: 3, type: dataType.uint8 } }); } break; case 'night_switching': await entity.write('hvacThermostat', { 0x0411: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); break; case 'frost_guard': await entity.write('hvacThermostat', { 0x0412: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); break; case 'max_floor_temp': await entity.write('hvacThermostat', { 0x0414: { value: value, type: dataType.uint8 } }); break; case 'regulator_setpoint': await entity.write('hvacThermostat', { 0x0420: { value: value, type: dataType.uint8 } }); break; case 'regulation_mode': await entity.write('hvacThermostat', { 0x0421: { value: utils.getFromLookup(value, { 'thermostat': 0, 'regulator': 1, 'zzilent': 2 }), type: dataType.uint8 } }); break; case 'max_floor_guard': await entity.write('hvacThermostat', { 0x0423: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); break; case 'weekly_timer': await entity.write('hvacThermostat', { 0x0424: { value: utils.getFromLookup(value, { 'OFF': 0, 'ON': 1 }), type: dataType.boolean } }); break; case 'exteral_sensor_source': await entity.write('hvacThermostat', { 0x0428: { value: value, type: dataType.uint16 } }); break; default: // Unknown key throw new Error(`Unhandled key tzLocal.ctm_thermostat.convertSet ${key}`); } }, convertGet: async (entity, key, meta) => { switch (key) { case 'load': await entity.read('hvacThermostat', [0x0401]); break; case 'display_text': await entity.read('hvacThermostat', [0x0402]); break; case 'sensor': await entity.read('hvacThermostat', [0x0403]); break; case 'regulator_mode': await entity.read('hvacThermostat', [0x0405]); break; case 'power_status': await entity.read('hvacThermostat', [0x0406]); break; case 'night_switching': await entity.read('hvacThermostat', [0x0411]); break; case 'frost_guard': await entity.read('hvacThermostat', [0x0412]); break; case 'max_floor_temp': await entity.read('hvacThermostat', [0x0414]); break; case 'regulator_setpoint': await entity.read('hvacThermostat', [0x0420]); break; case 'regulation_mode': await entity.read('hvacThermostat', [0x0421]); break; case 'system_mode': await entity.read('hvacThermostat', [0x0422]); break; case 'max_floor_guard': await entity.read('hvacThermostat', [0x0423]); break; case 'weekly_timer': await entity.read('hvacThermostat', [0x0424]); break; case 'exteral_sensor_source': await entity.read('hvacThermostat', [0x0428]); break; default: // Unknown key throw new Error(`Unhandled key tzLocal.ctm_thermostat.convertGet ${key}`); } }, }, ctm_thermostat_preset: { key: ['preset'], convertSet: async (entity, key, value, meta) => { const presetLookup = { 'off': 0, 'away': 1, 'sleep': 2, 'home': 3 }; await entity.write('hvacThermostat', { 0x0422: { value: utils.getFromLookup(value, presetLookup), type: dataType.uint8 } }); }, }, ctm_thermostat_child_lock: { key: ['child_lock'], convertSet: async (entity, key, value, meta) => { await entity.write('hvacThermostat', { 0x0413: { value: utils.getFromLookup(value, { 'UNLOCK': 0, 'LOCK': 1 }), type: dataType.boolean } }); }, }, ctm_thermostat_gets: { key: ['mean_power', 'floor_temp', 'running_state', 'frost_guard_setpoint', 'external_temp', 'air_temp', 'floor_sensor_error', 'exteral_sensor_error', ], convertGet: async (entity, key, meta) => { switch (key) { case 'mean_power': await entity.read('hvacThermostat', [0x0408]); break; case 'floor_temp': await entity.read('hvacThermostat', [0x0409]); break; case 'running_state': await entity.read('hvacThermostat', [0x0415]); break; case 'frost_guard_setpoint': await entity.read('hvacThermostat', [0x0425]); break; case 'external_temp': await entity.read('hvacThermostat', [0x0426]); break; case 'air_temp': await entity.read('hvacThermostat', [0x0429]); break; case 'floor_sensor_error': await entity.read('hvacThermostat', [0x042B]); break; case 'exteral_sensor_error': await entity.read('hvacThermostat', [0x042C]); break; default: // Unknown key throw new Error(`Unhandled key tzLocal.ctm_thermostat.convertGet ${key}`); } }, }, ctm_group_config: { key: ['group_id'], convertGet: async (entity, key, meta) => { await entity.read(0xFEA7, [0x0000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, }, ctm_sove_guard: { key: [ 'alarm_status', 'change_battery', 'stove_temperature', 'ambient_temperature', 'active', 'runtime', 'runtime_timeout', 'reset_reason', 'dip_switch', 'sw_version', 'hw_version', 'bootloader_version', 'model', 'relay_address', 'current_flag', 'relay_current', 'relay_status', 'external_button', 'relay_alarm', 'relay_alarm_status', ], convertGet: async (entity, key, meta) => { switch (key) { case 'alarm_status': await entity.read(0xFFC9, [0x0001], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'battery_low': await entity.read(0xFFC9, [0x0002], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'stove_temperature': await entity.read(0xFFC9, [0x0003], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'ambient_temperature': await entity.read(0xFFC9, [0x0004], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'active': await entity.read(0xFFC9, [0x0005], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'runtime': await entity.read(0xFFC9, [0x0006], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'runtime_timeout': await entity.read(0xFFC9, [0x0007], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'reset_reason': await entity.read(0xFFC9, [0x0008], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'dip_switch': await entity.read(0xFFC9, [0x0009], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'sw_version': await entity.read(0xFFC9, [0x000A], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'hw_version': await entity.read(0xFFC9, [0x000B], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'bootloader_version': await entity.read(0xFFC9, [0x000C], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'model': await entity.read(0xFFC9, [0x000D], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'relay_address': await entity.read(0xFFC9, [0x0010], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'current_flag': await entity.read(0xFFC9, [0x0100], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'relay_current': await entity.read(0xFFC9, [0x0101], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'relay_status': await entity.read(0xFFC9, [0x0102], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'external_button': await entity.read(0xFFC9, [0x0103], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'relay_alarm': await entity.read(0xFFC9, [0x0104], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; case 'relay_alarm_status': await entity.read(0xFFC9, [0x0105], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); break; default: // Unknown key throw new Error(`Unhandled key tzLocal.ctm_sove_guard.convertGet ${key}`); } }, }, }; const definitions = [ { zigbeeModel: ['mTouch Dim', 'DimmerPille'], model: 'mTouch_Dim', vendor: 'CTM Lyng', description: 'mTouch Dim OP, touch dimmer', fromZigbee: [fromZigbee_1.default.on_off, fromZigbee_1.default.brightness, fromZigbee_1.default.lighting_ballast_configuration], toZigbee: [toZigbee_1.default.on_off, toZigbee_1.default.light_onoff_brightness, toZigbee_1.default.light_brightness_move, toZigbee_1.default.ballast_config], meta: { disableDefaultResponse: true }, ota: ota.zigbeeOTA, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg']); await endpoint.read('genOnOff', ['onOff']); await reporting.onOff(endpoint); await endpoint.read('genLevelCtrl', ['currentLevel']); await reporting.brightness(endpoint); await endpoint.read('lightingBallastCfg', ['minLevel', 'maxLevel', 'powerOnLevel']); await endpoint.configureReporting('lightingBallastCfg', [{ attribute: 'minLevel', minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: null }]); await endpoint.configureReporting('lightingBallastCfg', [{ attribute: 'maxLevel', minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: null }]); await endpoint.configureReporting('lightingBallastCfg', [{ attribute: 'powerOnLevel', minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: null }]); }, exposes: [e.light_brightness(), e.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(99) .withDescription('Specifies the minimum brightness value'), e.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(99) .withDescription('Specifies the maximum brightness value'), e.numeric('ballast_power_on_level', ea.ALL).withValueMin(1).withValueMax(99) .withDescription('Specifies the initialisation light level. Can not be set lower than "ballast_minimum_level"')], whiteLabel: [ { vendor: 'CTM Lyng', model: 'CTM_DimmerPille', description: 'CTM Lyng DimmerPille', fingerprint: [{ modelID: 'DimmerPille' }] }, ], }, { zigbeeModel: ['mTouch Bryter'], model: 'mTouch_Bryter', vendor: 'CTM Lyng', description: 'mTouch Bryter OP, 3 channel switch', fromZigbee: [fromZigbee_1.default.temperature, fromZigbee_1.default.battery, fromZigbee_1.default.command_recall, fromZigbee_1.default.command_on, fromZigbee_1.default.command_off, fromZigbee_1.default.command_toggle, fromZigbee_1.default.command_move, fromZigbee_1.default.command_stop, fzLocal.ctm_group_config], toZigbee: [], meta: { battery: { voltageToPercentage: '3V_2500_3200' } }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement']); await reporting.batteryVoltage(endpoint); await endpoint.read('msTemperatureMeasurement', ['measuredValue']); await reporting.temperature(endpoint, { min: constants.repInterval.MINUTES_10, max: constants.repInterval.HOUR, change: 100 }); await endpoint.read(0xFEA7, [0x0000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, exposes: [e.battery(), e.temperature(), e.action(['recall_1', 'recall_2', 'recall_3', 'on', 'off', 'toggle', 'brightness_move_down', 'brightness_move_up', 'brightness_stop']), e.numeric('group_id', ea.STATE) .withDescription('The device sends commands with this group ID. Put dvices in this group to control them.')], }, { zigbeeModel: ['mTouch One'], model: 'mTouch_One', vendor: 'CTM Lyng', description: 'mTouch One OP, touch thermostat', fromZigbee: [fromZigbee_1.default.thermostat, fzLocal.ctm_thermostat], toZigbee: [toZigbee_1.default.thermostat_occupied_heating_setpoint, toZigbee_1.default.thermostat_local_temperature, tzLocal.ctm_thermostat, tzLocal.ctm_thermostat_preset, tzLocal.ctm_thermostat_child_lock, tzLocal.ctm_thermostat_gets], ota: ota.zigbeeOTA, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['hvacThermostat']); await endpoint.read('hvacThermostat', ['localTemp', 'occupiedHeatingSetpoint']); await reporting.thermostatTemperature(endpoint); await reporting.thermostatOccupiedHeatingSetpoint(endpoint); await endpoint.read('hvacThermostat', [0x0401]); await endpoint.read('hvacThermostat', [0x0402]); // Regulator mode await endpoint.read('hvacThermostat', [0x0405]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0405, type: dataType.boolean }, minimumReportInterval: 1, maximumReportInterval: constants.repInterval.MAX, reportableChange: null }]); // Power consumption await endpoint.read('hvacThermostat', [0x0408]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0408, type: dataType.uint16 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 5 }]); // Floor temp sensor await endpoint.read('hvacThermostat', [0x0409]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0409, type: dataType.int16 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 10 }]); // Frost guard await endpoint.read('hvacThermostat', [0x0412]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0412, type: dataType.boolean }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.MAX, reportableChange: null }]); // Child lock active/inactive await endpoint.read('hvacThermostat', [0x0413]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0413, type: dataType.boolean }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.MAX, reportableChange: null }]); // Regulator setpoint await endpoint.read('hvacThermostat', [0x0420]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0420, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1 }]); // Operation mode await endpoint.read('hvacThermostat', [0x0422]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0422, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1 }]); // Air temp sensor await endpoint.read('hvacThermostat', [0x0429]); await endpoint.configureReporting('hvacThermostat', [{ attribute: { ID: 0x0429, type: dataType.int16 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 10 }]); }, exposes: [e.child_lock(), e.climate() .withSetpoint('occupied_heating_setpoint', 5, 40, 1) .withLocalTemperature() .withSystemMode(['off', 'heat']) .withPreset(['off', 'away', 'sleep', 'home']) .withRunningState(['idle', 'heat']), e.numeric('load', ea.ALL).withUnit('W') .withDescription('Load in W when heating is on (between 0-3600 W). The thermostat uses the value as input to the ' + 'mean_power calculation.') .withValueMin(0).withValueMax(3600), e.text('display_text', ea.ALL) .withDescription('Displayed text on thermostat display (zone). Max 19 characters'), e.binary('regulator_mode', ea.ALL, 'regulator', 'thermostat') .withDescription('Device in regulator or thermostat mode.'), e.numeric('mean_power', ea.STATE_GET).withUnit('W') .withDescription('Reports average power usage last 10 minutes'), e.numeric('floor_temp', ea.STATE_GET).withUnit('°C') .withDescription('Current temperature measured from the floor sensor'), e.binary('frost_guard', ea.ALL, 'ON', 'OFF') .withDescription('When frost guard is ON, it is activated when the thermostat is switched OFF with the ON/OFF button.' + 'At the same time, the display will fade and the text "Frostsikring x °C" appears in the display and remains until the ' + 'thermostat is switched on again.'), e.numeric('regulator_setpoint', ea.ALL).withUnit('%') .withDescription('Setpoint in %, use only when the thermostat is in regulator mode.') .withValueMin(1).withValueMax(99), e.numeric('air_temp', ea.STATE_GET).withUnit('°C') .withDescription('Current temperature measured from the air sensor'), ], }, { zigbeeModel: ['mStikk Outlet', 'mStikk 16A', 'mStikk 25A', 'Tavlerele 25A'], model: 'mStikk_Outlet', vendor: 'CTM Lyng', description: 'mStikk OP, wall socket', fromZigbee: [fromZigbee_1.default.on_off, fromZigbee_1.default.electrical_measurement, fromZigbee_1.default.metering], toZigbee: [toZigbee_1.default.on_off], ota: ota.zigbeeOTA, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']); await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor']); await endpoint.read('haElectricalMeasurement', ['acCurrentMultiplier', 'acCurrentDivisor']); await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']); await reporting.readMeteringMultiplierDivisor(endpoint); await endpoint.read('genOnOff', ['onOff']); await reporting.onOff(endpoint); await reporting.rmsVoltage(endpoint, { change: 100 }); await reporting.rmsCurrent(endpoint); await reporting.activePower(endpoint); await reporting.currentSummDelivered(endpoint); }, exposes: [e.power(), e.current(), e.voltage(), e.switch(), e.energy()], }, { zigbeeModel: ['mKomfy'], model: 'mKomfy_Sensor', vendor: 'CTM Lyng', description: 'mKomfy, stove guard', fromZigbee: [fromZigbee_1.default.temperature, fromZigbee_1.default.battery, fzLocal.ctm_sove_guard], toZigbee: [], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement', 0xFFC9]); await reporting.batteryPercentageRemaining(endpoint); // await endpoint.read('msTemperatureMeasurement', ['measuredValue']); await reporting.temperature(endpoint, { min: constants.repInterval.MINUTES_10, max: constants.repInterval.HOUR, change: 100 }); // Alarm status // await endpoint.read(0xFFC9, [0x0001], {manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS}); await endpoint.configureReporting(0xFFC9, [{ attribute: { ID: 0x0001, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 0 }], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); // Change battery // await endpoint.read(0xFFC9, [0x0002], {manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS}); await endpoint.configureReporting(0xFFC9, [{ attribute: { ID: 0x0002, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.MAX, reportableChange: 0 }], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); // Active // await endpoint.read(0xFFC9, [0x0005], {manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS}); await endpoint.configureReporting(0xFFC9, [{ attribute: { ID: 0x0005, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 0 }], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, exposes: [e.battery(), e.battery_low(), e.temperature(), e.enum('alarm_status', ea.STATE, ['ok', 'tamper', 'high_temperatur', 'timer', 'battery_alarm', 'error', 'unknown']) .withDescription('Alarm status.'), e.binary('active', ea.STATE, true, false) .withDescription('Stove guard active/inactive (Stove in use)')], }, { zigbeeModel: ['mTouch Astro'], model: 'mTouch_Astro', vendor: 'CTM Lyng', description: 'mTouch Astro OP, astro clock', fromZigbee: [fromZigbee_1.default.on_off, fromZigbee_1.default.command_on, fromZigbee_1.default.command_off, fzLocal.ctm_device_mode, fzLocal.ctm_device_enabled, fzLocal.ctm_child_lock, fzLocal.ctm_group_config], toZigbee: [toZigbee_1.default.on_off, tzLocal.ctm_device_enabled], meta: { disableDefaultResponse: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']); await endpoint.read('genOnOff', ['onOff']); await reporting.onOff(endpoint); // Device mode await endpoint.read('genOnOff', [0x2200]); await endpoint.configureReporting('genOnOff', [{ attribute: { ID: 0x2200, type: dataType.uint8 }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 0 }]); await endpoint.read('genOnOff', [0x2201]); await endpoint.configureReporting('genOnOff', [{ attribute: { ID: 0x2201, type: dataType.boolean }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: null }]); await endpoint.read('genOnOff', [0x2202]); await endpoint.configureReporting('genOnOff', [{ attribute: { ID: 0x2202, type: dataType.boolean }, minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: null }]); await endpoint.read(0xFEA7, [0x0000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS }); }, exposes: [e.switch(), e.action(['on', 'off']), e.enum('device_mode', ea.STATE, ['astro_clock', 'timer', 'daily_timer', 'weekly_timer']) .withDescription('Device mode.'), e.binary('device_enabled', ea.ALL, 'ON', 'OFF') .withDescription('Turn the device on or off'), e.binary('child_lock', ea.STATE, 'locked', 'unlocked') .withDescription('Physical input on the device enabled/disabled'), e.numeric('group_id', ea.STATE) .withDescription('The device sends commands with this group ID. Put devices in this group to control them.'), ], }, { zigbeeModel: ['AX Water Sensor'], model: 'AX_Water_Sensor', vendor: 'CTM Lyng', description: 'AX Water Sensor, water leakage detector', fromZigbee: [fromZigbee_1.default.battery, fromZigbee_1.default.ias_enroll, fzLocal.ctm_water_leak_alarm], toZigbee: [], meta: { battery: { voltageToPercentage: '3V_2500_3200' } }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'ssIasZone']); await reporting.batteryVoltage(endpoint); await endpoint.read('ssIasZone', ['iasCieAddr', 'zoneSt