UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

544 lines 36.2 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 exposes = __importStar(require("../lib/exposes")); const fromZigbee_1 = __importDefault(require("../converters/fromZigbee")); const toZigbee_1 = __importDefault(require("../converters/toZigbee")); const ota = __importStar(require("../lib/ota")); const constants = __importStar(require("../lib/constants")); const reporting = __importStar(require("../lib/reporting")); const e = exposes.presets; const ea = exposes.access; const definitions = [ { // eTRV0100 is the same as Hive TRV001 and Popp eT093WRO. If implementing anything, please consider // changing those two too. zigbeeModel: ['eTRV0100', 'eTRV0101', 'eTRV0103', 'TRV001', 'TRV003', 'eT093WRO', 'eT093WRG', 'eTRV0103'], model: '014G2461', vendor: 'Danfoss', description: 'Ally thermostat', whiteLabel: [ { vendor: 'Danfoss', model: '014G2463' }, { vendor: 'Hive', model: 'UK7004240', description: 'Radiator valve', fingerprint: [{ modelID: 'TRV001' }, { modelID: 'TRV003' }] }, { vendor: 'Popp', model: '701721', description: 'Smart thermostat', fingerprint: [{ modelID: 'eT093WRO' }, { modelID: 'eT093WRG' }] }, ], meta: { thermostat: { dontMapPIHeatingDemand: true } }, fromZigbee: [fromZigbee_1.default.battery, fromZigbee_1.default.thermostat, fromZigbee_1.default.thermostat_weekly_schedule, fromZigbee_1.default.hvac_user_interface, fromZigbee_1.default.danfoss_thermostat, fromZigbee_1.default.danfoss_thermostat_setpoint_scheduled], toZigbee: [toZigbee_1.default.danfoss_thermostat_occupied_heating_setpoint, toZigbee_1.default.thermostat_local_temperature, toZigbee_1.default.danfoss_mounted_mode_active, toZigbee_1.default.danfoss_mounted_mode_control, toZigbee_1.default.danfoss_thermostat_vertical_orientation, toZigbee_1.default.danfoss_algorithm_scale_factor, toZigbee_1.default.danfoss_heat_available, toZigbee_1.default.danfoss_heat_required, toZigbee_1.default.danfoss_day_of_week, toZigbee_1.default.danfoss_trigger_time, toZigbee_1.default.danfoss_window_open_internal, toZigbee_1.default.danfoss_window_open_external, toZigbee_1.default.danfoss_load_estimate, toZigbee_1.default.danfoss_viewing_direction, toZigbee_1.default.danfoss_external_measured_room_sensor, toZigbee_1.default.danfoss_radiator_covered, toZigbee_1.default.thermostat_keypad_lockout, toZigbee_1.default.thermostat_system_mode, toZigbee_1.default.danfoss_load_balancing_enable, toZigbee_1.default.danfoss_load_room_mean, toZigbee_1.default.thermostat_weekly_schedule, toZigbee_1.default.thermostat_clear_weekly_schedule, toZigbee_1.default.thermostat_programming_operation_mode, toZigbee_1.default.danfoss_window_open_feature, toZigbee_1.default.danfoss_preheat_status, toZigbee_1.default.danfoss_adaptation_status, toZigbee_1.default.danfoss_adaptation_settings, toZigbee_1.default.danfoss_adaptation_control, toZigbee_1.default.danfoss_regulation_setpoint_offset, toZigbee_1.default.danfoss_thermostat_occupied_heating_setpoint_scheduled], exposes: (device, options) => { const maxSetpoint = ['TRV001', 'TRV003'].includes(device?.modelID) ? 32 : 35; return [ e.linkquality(), e.battery(), e.keypad_lockout(), e.programming_operation_mode(), e.binary('mounted_mode_active', ea.STATE_GET, true, false) .withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' + 'the radiator) or `true` for not mounted (after factory reset)'), e.binary('mounted_mode_control', ea.ALL, true, false) .withDescription('Set the unit mounting mode. `false` Go to Mounted Mode or `true` Go to Mounting Mode'), e.binary('thermostat_vertical_orientation', ea.ALL, true, false) .withDescription('Thermostat Orientation. This is important for the PID in how it assesses temperature. ' + '`false` Horizontal or `true` Vertical'), e.binary('viewing_direction', ea.ALL, true, false) .withDescription('Viewing/display direction, `false` normal or `true` upside-down'), e.binary('heat_available', ea.ALL, true, false) .withDescription('Not clear how this affects operation. However, it would appear that the device does not execute any ' + 'motor functions if this is set to false. This may be a means to conserve battery during periods that the heating ' + 'system is not energized (e.g. during summer). `false` No Heat Available or `true` Heat Available'), e.binary('heat_required', ea.STATE_GET, true, false) .withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'), e.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally']) .withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'), e.climate().withSetpoint('occupied_heating_setpoint', 5, maxSetpoint, 0.5).withLocalTemperature().withPiHeatingDemand() .withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE), e.numeric('occupied_heating_setpoint_scheduled', ea.ALL) .withValueMin(5).withValueMax(maxSetpoint).withValueStep(0.5).withUnit('°C') .withDescription('Scheduled change of the setpoint. Alternative method for changing the setpoint. In the opposite ' + 'to occupied_heating_setpoint it does not trigger an aggressive response from the actuator. ' + '(more suitable for scheduled changes)'), e.numeric('external_measured_room_sensor', ea.ALL) .withDescription('The temperature sensor of the TRV is — due to its design — relatively close to the heat source ' + '(i.e. the hot water in the radiator). Thus there are situations where the `local_temperature` measured by the ' + 'TRV is not accurate enough: If the radiator is covered behind curtains or furniture, if the room is rather big, or ' + 'if the radiator itself is big and the flow temperature is high, then the temperature in the room may easily diverge ' + 'from the `local_temperature` measured by the TRV by 5°C to 8°C. In this case you might choose to use an external ' + 'room sensor and send the measured value of the external room sensor to the `External_measured_room_sensor` property.' + 'The way the TRV operates on the `External_measured_room_sensor` depends on the setting of the `Radiator_covered` ' + 'property: If `Radiator_covered` is `false` (Auto Offset Mode): You *must* set the `External_measured_room_sensor` ' + 'property *at least* every 3 hours. After 3 hours the TRV disables this function and resets the value of the ' + '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' + 'property *at most* every 30 minutes or every 0.1K change in measured room temperature.' + 'If `Radiator_covered` is `true` (Room Sensor Mode): You *must* set the `External_measured_room_sensor` property *at ' + 'least* every 30 minutes. After 35 minutes the TRV disables this function and resets the value of the ' + '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' + 'property *at most* every 5 minutes or every 0.1K change in measured room temperature.') .withValueMin(-8000).withValueMax(3500), e.binary('radiator_covered', ea.ALL, true, false) .withDescription('Controls whether the TRV should solely rely on an external room sensor or operate in offset mode. ' + '`false` = Auto Offset Mode (use this e.g. for exposed radiators) or `true` = Room Sensor Mode (use this e.g. for ' + 'covered radiators). Please note that this flag only controls how the TRV operates on the value of ' + '`External_measured_room_sensor`; only setting this flag without setting the `External_measured_room_sensor` ' + 'has no (noticeable?) effect.'), e.binary('window_open_feature', ea.ALL, true, false) .withDescription('Whether or not the window open feature is enabled'), e.enum('window_open_internal', ea.STATE_GET, ['quarantine', 'closed', 'hold', 'open', 'external_open']) .withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' + '3=Open window detected, 4=In window open state from external but detected closed locally'), e.binary('window_open_external', ea.ALL, true, false) .withDescription('Set if the window is open or close. This setting will trigger a change in the internal ' + 'window and heating demand. `false` (windows are closed) or `true` (windows are open)'), e.enum('day_of_week', ea.ALL, ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'away_or_vacation']) .withDescription('Exercise day of week: 0=Sun...6=Sat, 7=undefined'), e.numeric('trigger_time', ea.ALL).withValueMin(0).withValueMax(65535) .withDescription('Exercise trigger time. Minutes since midnight (65535=undefined). Range 0 to 1439'), e.numeric('algorithm_scale_factor', ea.ALL).withValueMin(1).withValueMax(10) .withDescription('Scale factor of setpoint filter timeconstant ("aggressiveness" of control algorithm) ' + '1= Quick ... 5=Moderate ... 10=Slow'), e.binary('load_balancing_enable', ea.ALL, true, false) .withDescription('Whether or not the thermostat acts as standalone thermostat or shares load with other ' + 'thermostats in the room. The gateway must update load_room_mean if enabled.'), e.numeric('load_room_mean', ea.ALL) .withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)') .withValueMin(-8000).withValueMax(3600), e.numeric('load_estimate', ea.STATE_GET) .withDescription('Load estimate on this radiator') .withValueMin(-8000).withValueMax(3600), e.binary('preheat_status', ea.STATE_GET, true, false) .withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'), e.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost']) .withDescription('Status of adaptation run: None (before first run), In Progress, Valve Characteristic Found, ' + 'Valve Characteristic Lost'), e.binary('adaptation_run_settings', ea.ALL, true, false) .withDescription('Automatic adaptation run enabled (the one during the night)'), e.enum('adaptation_run_control', ea.ALL, ['none', 'initiate_adaptation', 'cancel_adaptation']) .withDescription('Adaptation run control: Initiate Adaptation Run or Cancel Adaptation Run'), e.numeric('regulation_setpoint_offset', ea.ALL) .withDescription('Regulation SetPoint Offset in range -2.5°C to 2.5°C in steps of 0.1°C. Value 2.5°C = 25.') .withValueMin(-25).withValueMax(25) ]; }, ota: ota.zigbeeOTA, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); const options = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DANFOSS_A_S }; await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']); // standard ZCL attributes await reporting.batteryPercentageRemaining(endpoint); await reporting.thermostatTemperature(endpoint); await reporting.thermostatPIHeatingDemand(endpoint); await reporting.thermostatOccupiedHeatingSetpoint(endpoint); // danfoss attributes await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossMountedModeActive', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.MAX, reportableChange: 1, }], options); await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossWindowOpenInternal', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1, }], options); await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossHeatRequired', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1, }], options); await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossExternalMeasuredRoomSensor', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.MAX, reportableChange: 1, }], options); await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossAdaptionRunStatus', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1, }], options); try { await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossPreheatStatus', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.MAX, reportableChange: 1, }], options); } catch (e) { /* not supported by all */ } try { await endpoint.read('hvacThermostat', [ 'danfossWindowOpenFeatureEnable', 'danfossWindowOpenExternal', 'danfossDayOfWeek', 'danfossTriggerTime', 'danfossAlgorithmScaleFactor', 'danfossHeatAvailable', 'danfossMountedModeControl', 'danfossMountedModeActive', 'danfossExternalMeasuredRoomSensor', 'danfossRadiatorCovered', 'danfossLoadBalancingEnable', 'danfossLoadRoomMean', 'danfossAdaptionRunControl', 'danfossAdaptionRunSettings', 'danfossRegulationSetpointOffset', ], options); } catch (e) { /* not supported by all https://github.com/Koenkk/zigbee2mqtt/issues/11872 */ } // read systemMode to have an initial value await endpoint.read('hvacThermostat', ['systemMode']); // read keypadLockout, we don't need reporting as it cannot be set physically on the device await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout']); // Seems that it is bug in Danfoss, device does not asks for the time with binding // So, we need to write time during configure (same as for HEIMAN devices) const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000); // Time-master + synchronised const values = { timeStatus: 3, time: time, timeZone: ((new Date()).getTimezoneOffset() * -1) * 60 }; endpoint.write('genTime', values); }, }, { fingerprint: [ { modelID: '0x8020', manufacturerName: 'Danfoss' }, // RT24V Display { modelID: '0x8021', manufacturerName: 'Danfoss' }, // RT24V Display Floor sensor { modelID: '0x8030', manufacturerName: 'Danfoss' }, // RTbattery Display { modelID: '0x8031', manufacturerName: 'Danfoss' }, // RTbattery Display Infrared { modelID: '0x8034', manufacturerName: 'Danfoss' }, // RTbattery Dial { modelID: '0x8035', manufacturerName: 'Danfoss' }, // RTbattery Dial Infrared ], model: 'Icon', vendor: 'Danfoss', description: 'Icon floor heating (regulator, Zigbee module & thermostats)', fromZigbee: [ fromZigbee_1.default.danfoss_icon_regulator, fromZigbee_1.default.danfoss_thermostat, fromZigbee_1.default.danfoss_icon_battery, fromZigbee_1.default.thermostat ], toZigbee: [ toZigbee_1.default.thermostat_local_temperature, toZigbee_1.default.thermostat_occupied_heating_setpoint, toZigbee_1.default.thermostat_system_mode, toZigbee_1.default.thermostat_running_state, toZigbee_1.default.thermostat_min_heat_setpoint_limit, toZigbee_1.default.thermostat_max_heat_setpoint_limit, toZigbee_1.default.danfoss_output_status, toZigbee_1.default.danfoss_room_status_code, toZigbee_1.default.danfoss_system_status_water, toZigbee_1.default.danfoss_system_status_code, toZigbee_1.default.danfoss_multimaster_role, ], meta: { multiEndpoint: true, thermostat: { dontMapPIHeatingDemand: true } }, // ota: ota.zigbeeOTA, endpoint: (device) => { return { 'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4, 'l5': 5, 'l6': 6, 'l7': 7, 'l8': 8, 'l9': 9, 'l10': 10, 'l11': 11, 'l12': 12, 'l13': 13, 'l14': 14, 'l15': 15, 'l16': 232, }; }, exposes: [].concat(((endpointsCount) => { const features = []; for (let i = 1; i <= endpointsCount; i++) { const epName = `l${i}`; if (i != 16) { features.push(e.battery().withEndpoint(epName)); features.push(e.climate().withSetpoint('occupied_heating_setpoint', 5, 35, 0.5) .withLocalTemperature().withRunningState(['idle', 'heat']).withSystemMode(['heat']).withEndpoint(epName)); features.push(e.numeric('abs_min_heat_setpoint_limit', ea.STATE) .withUnit('°C').withEndpoint(epName) .withDescription('Absolute min temperature allowed on the device')); features.push(e.numeric('abs_max_heat_setpoint_limit', ea.STATE) .withUnit('°C').withEndpoint(epName) .withDescription('Absolute max temperature allowed on the device')); features.push(e.numeric('min_heat_setpoint_limit', ea.ALL) .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName).withDescription('Min temperature limit set on the device')); features.push(e.numeric('max_heat_setpoint_limit', ea.ALL) .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName).withDescription('Max temperature limit set on the device')); features.push(e.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally']) .withEndpoint(epName)); features.push(e.enum('output_status', ea.STATE_GET, ['inactive', 'active']) .withEndpoint(epName).withDescription('Danfoss Output Status [Active vs Inactive])')); features.push(e.enum('room_status_code', ea.STATE_GET, ['no_error', 'missing_rt', 'rt_touch_error', 'floor_sensor_short_circuit', 'floor_sensor_disconnected']) .withEndpoint(epName).withDescription('Thermostat status')); } else { features.push(e.enum('system_status_code', ea.STATE_GET, ['no_error', 'missing_expansion_board', 'missing_radio_module', 'missing_command_module', 'missing_master_rail', 'missing_slave_rail_no_1', 'missing_slave_rail_no_2', 'pt1000_input_short_circuit', 'pt1000_input_open_circuit', 'error_on_one_or_more_output']).withEndpoint('l16').withDescription('Regulator Status')); features.push(e.enum('system_status_water', ea.STATE_GET, ['hot_water_flow_in_pipes', 'cool_water_flow_in_pipes']) .withEndpoint('l16').withDescription('Water Status of Regulator')); features.push(e.enum('multimaster_role', ea.STATE_GET, ['invalid_unused', 'master', 'slave_1', 'slave_2']) .withEndpoint('l16').withDescription('Regulator role (Master vs Slave)')); } } return features; })(16)), configure: async (device, coordinatorEndpoint) => { const options = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DANFOSS_A_S }; for (let i = 1; i <= 15; i++) { const endpoint = device.getEndpoint(i); if (typeof endpoint !== 'undefined') { await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg']); await reporting.batteryPercentageRemaining(endpoint, { min: constants.repInterval.HOUR, max: 43200, change: 1 }); await reporting.thermostatTemperature(endpoint, { min: 0, max: constants.repInterval.MINUTES_10, change: 10 }); await reporting.thermostatOccupiedHeatingSetpoint(endpoint, { min: 0, max: constants.repInterval.MINUTES_10, change: 10 }); await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossOutputStatus', minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.MINUTES_10, reportableChange: 1, }], options); // Danfoss Icon Thermostat Specific await endpoint.read('hvacThermostat', [ 'danfossOutputStatus', 'danfossRoomStatusCode' ], options); // Standard Thermostat await endpoint.read('hvacThermostat', ['localTemp']); await endpoint.read('hvacThermostat', ['occupiedHeatingSetpoint']); await endpoint.read('hvacThermostat', ['systemMode']); await endpoint.read('hvacThermostat', ['setpointChangeSource']); await endpoint.read('hvacThermostat', ['absMinHeatSetpointLimit']); await endpoint.read('hvacThermostat', ['absMaxHeatSetpointLimit']); await endpoint.read('hvacThermostat', ['minHeatSetpointLimit']); await endpoint.read('hvacThermostat', ['maxHeatSetpointLimit']); await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']); } } // Danfoss Icon Regulator Specific const endpoint232 = device.getEndpoint(232); await reporting.bind(endpoint232, coordinatorEndpoint, ['haDiagnostic']); await endpoint232.read('haDiagnostic', [ 'danfossSystemStatusCode', 'danfossSystemStatusWater', 'danfossMultimasterRole' ], options); }, }, { fingerprint: [ { modelID: '0x0210', manufacturerName: 'Danfoss' }, // Icon2 Basic Main Controller { modelID: '0x0211', manufacturerName: 'Danfoss' }, // Icon2 Advanced Main Controller { modelID: '0x8040', manufacturerName: 'Danfoss' }, // Icon2 Room Thermostat { modelID: '0x8041', manufacturerName: 'Danfoss' }, // Icon2 Featured (Infrared) Room Thermostat { modelID: '0x0042', manufacturerName: 'Danfoss' }, // Icon2 Sensor ], model: 'Icon2', vendor: 'Danfoss', description: 'Icon2 Main Controller, Room Thermostat or Sensor', fromZigbee: [ fromZigbee_1.default.danfoss_icon_battery, fromZigbee_1.default.thermostat, fromZigbee_1.default.danfoss_thermostat, fromZigbee_1.default.danfoss_icon_floor_sensor, fromZigbee_1.default.danfoss_icon_hvac_user_interface, fromZigbee_1.default.temperature, fromZigbee_1.default.humidity, fromZigbee_1.default.danfoss_icon_regulator, ], toZigbee: [ toZigbee_1.default.thermostat_local_temperature, toZigbee_1.default.thermostat_occupied_heating_setpoint, toZigbee_1.default.thermostat_min_heat_setpoint_limit, toZigbee_1.default.thermostat_max_heat_setpoint_limit, toZigbee_1.default.thermostat_system_mode, toZigbee_1.default.danfoss_room_status_code, toZigbee_1.default.danfoss_output_status, toZigbee_1.default.danfoss_floor_sensor_mode, toZigbee_1.default.danfoss_floor_min_setpoint, toZigbee_1.default.danfoss_floor_max_setpoint, toZigbee_1.default.thermostat_keypad_lockout, toZigbee_1.default.temperature, toZigbee_1.default.humidity, toZigbee_1.default.danfoss_system_status_code, toZigbee_1.default.danfoss_system_status_water, toZigbee_1.default.danfoss_multimaster_role, ], meta: { multiEndpoint: true, thermostat: { dontMapPIHeatingDemand: true } }, exposes: [].concat(((endpointsCount) => { const features = []; for (let i = 1; i <= endpointsCount; i++) { if (i < 16) { const epName = `${i}`; features.push(e.battery().withEndpoint(epName)); features.push(e.climate() .withSetpoint('occupied_heating_setpoint', 5, 35, 0.5) .withLocalTemperature() .withSystemMode(['heat']) .withRunningState(['idle', 'heat'], ea.STATE) .withEndpoint(epName)); features.push(e.numeric('min_heat_setpoint_limit', ea.ALL) .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName) .withDescription('Min temperature limit set on the device')); features.push(e.numeric('max_heat_setpoint_limit', ea.ALL) .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName) .withDescription('Max temperature limit set on the device')); features.push(e.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally']) .withEndpoint(epName)); features.push(e.enum('output_status', ea.STATE_GET, ['inactive', 'active']) .withEndpoint(epName) .withDescription('Actuator status)')); features.push(e.enum('room_status_code', ea.STATE_GET, ['no_error', 'missing_rt', 'rt_touch_error', 'floor_sensor_short_circuit', 'floor_sensor_disconnected']) .withEndpoint(epName) .withDescription('Thermostat status')); features.push(e.enum('room_floor_sensor_mode', ea.STATE_GET, ['comfort', 'floor_only', 'dual_mode']) .withEndpoint(epName) .withDescription('Floor sensor mode')); features.push(e.numeric('floor_min_setpoint', ea.ALL) .withValueMin(18).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName) .withDescription('Min floor temperature')); features.push(e.numeric('floor_max_setpoint', ea.ALL) .withValueMin(18).withValueMax(35).withValueStep(0.5).withUnit('°C') .withEndpoint(epName) .withDescription('Max floor temperature')); features.push(e.numeric('temperature', ea.STATE_GET) .withUnit('°C') .withEndpoint(epName) .withDescription('Floor temperature')); features.push(e.numeric('humidity', ea.STATE_GET) .withUnit('%') .withEndpoint(epName) .withDescription('Humidity')); } else { features.push(e.enum('system_status_code', ea.STATE_GET, ['no_error', 'missing_expansion_board', 'missing_radio_module', 'missing_command_module', 'missing_master_rail', 'missing_slave_rail_no_1', 'missing_slave_rail_no_2', 'pt1000_input_short_circuit', 'pt1000_input_open_circuit', 'error_on_one_or_more_output']) .withEndpoint('232') .withDescription('Main Controller Status')); features.push(e.enum('system_status_water', ea.STATE_GET, ['hot_water_flow_in_pipes', 'cool_water_flow_in_pipes']) .withEndpoint('232') .withDescription('Main Controller Water Status')); features.push(e.enum('multimaster_role', ea.STATE_GET, ['invalid_unused', 'master', 'slave_1', 'slave_2']) .withEndpoint('232') .withDescription('Main Controller Role')); } } return features; })(16)), configure: async (device, coordinatorEndpoint) => { const options = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DANFOSS_A_S }; // Danfoss Icon2 Main Controller Specific Endpoint const mainController = device.getEndpoint(232); for (let i = 1; i <= 15; i++) { const endpoint = device.getEndpoint(i); if (typeof endpoint == 'undefined') { continue; } await reporting.bind(endpoint, coordinatorEndpoint, [ 'genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', ]); await reporting.batteryPercentageRemaining(endpoint); await reporting.thermostatTemperature(endpoint); await reporting.thermostatOccupiedHeatingSetpoint(endpoint); await reporting.temperature(endpoint, { change: 10 }); await reporting.humidity(endpoint); await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']); await endpoint.read('hvacThermostat', [ 'localTemp', 'occupiedHeatingSetpoint', 'minHeatSetpointLimit', 'maxHeatSetpointLimit', 'systemMode', ]); await endpoint.read('hvacThermostat', [ 'danfossRoomFloorSensorMode', 'danfossFloorMinSetpoint', 'danfossFloorMaxSetpoint', ], options); await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout']); await endpoint.read('msTemperatureMeasurement', ['measuredValue']); await endpoint.read('msRelativeHumidity', ['measuredValue']); // Different attributes depending on if it's Main Сontroller or a single thermostat if (typeof mainController == 'undefined') { await endpoint.read('genBasic', ['modelId', 'powerSource']); } else { await endpoint.configureReporting('hvacThermostat', [{ attribute: 'danfossOutputStatus', minimumReportInterval: 0, maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1, }], options); await endpoint.read('hvacThermostat', ['setpointChangeSource']); await endpoint.read('hvacThermostat', ['danfossOutputStatus', 'danfossRoomStatusCode'], options); } } // Danfoss Icon2 Main Controller Specific if (typeof mainController != 'undefined') { await reporting.bind(mainController, coordinatorEndpoint, ['genBasic', 'haDiagnostic']); await mainController.read('genBasic', [ 'modelId', 'powerSource', 'appVersion', 'stackVersion', 'hwVersion', 'dateCode', ]); await mainController.read('haDiagnostic', [ 'danfossSystemStatusCode', 'danfossSystemStatusWater', 'danfossMultimasterRole', ], options); } }, }, ]; exports.default = definitions; module.exports = definitions; //# sourceMappingURL=danfoss.js.map