Skip to content

Commit

Permalink
Add BRT-100-TRV (#2652)
Browse files Browse the repository at this point in the history
* Update exposes.js

* Update tuya.js

* Update fromZigbee.js

* Update toZigbee.js

* Update tuya.js

* Update exposes.js

* Update tuya.js

* Update fromZigbee.js

* Update toZigbee.js

* Update tuya.js

* Update moes.js

* Update toZigbee.js

* Update fromZigbee.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update fromZigbee.js

* Update toZigbee.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update exposes.js

* Update fromZigbee.js

* Update toZigbee.js

* Update fromZigbee.js

* Update toZigbee.js

* Update fromZigbee.js

* Update toZigbee.js

* Update moes.js

* Update fromZigbee.js

* Update toZigbee.js

* Update exposes.js

* Update moes.js

* Update exposes.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update moes.js

* Update fromZigbee.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
  • Loading branch information
vladi1234 and Koenkk committed Jun 10, 2021
1 parent 8360bc2 commit 5b524ea
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 2 deletions.
65 changes: 65 additions & 0 deletions converters/fromZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -3047,6 +3047,71 @@ const converters = {
}
},
},
moesS_thermostat: {
cluster: 'manuSpecificTuya',
type: ['commandGetData', 'commandSetDataResponse'],
convert: (model, msg, publish, options, meta) => {
const dp = msg.data.dp; // First we get the data point ID
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
const presetLookup = {0: 'programming', 1: 'manual', 2: 'temporary_manual', 3: 'holiday'};
switch (dp) {
case tuya.dataPoints.moesSsystemMode:
return {preset: presetLookup[value]};
case tuya.dataPoints.moesSheatingSetpoint:
return {current_heating_setpoint: value};
case tuya.dataPoints.moesSlocalTemp:
return {local_temperature: (value / 10)};
case tuya.dataPoints.moesSboostHeating:
return {boost_heating: value ? 'ON' : 'OFF'};
case tuya.dataPoints.moesSboostHeatingCountdown:
return {boost_heating_countdown: value};
case tuya.dataPoints.moesSreset:
break;
case tuya.dataPoints.moesSwindowDetectionFunktion_A2:
return {window_detection: value ? 'ON' : 'OFF'};
case tuya.dataPoints.moesSwindowDetection:
return {window_detection: value ? 'ON' : 'OFF'};
case tuya.dataPoints.moesSchildLock:
return {child_lock: value ? 'LOCK' : 'UNLOCK'};
case tuya.dataPoints.moesSbattery:
return {battery: value};
case tuya.dataPoints.moesSschedule:
return {
programming_mode: {
weekday: ' ' + value[0] + 'h:' + value[1] + 'm ' + value[2]/2 + '°C' +
', ' + value[3] + 'h:' + value[4] + 'm ' + value[5]/2 + '°C' +
', ' + value[6] + 'h:' + value[7] + 'm ' + value[8]/2 + '°C' +
', ' + value[9] + 'h:' + value[10] + 'm ' + value[11]/2 + '°C ',
saturday: '' + value[12] + 'h:' + value[13] + 'm ' + value[14]/2 + '°C' +
', ' + value[15] + 'h:' + value[16] + 'm ' + value[17]/2 + '°C' +
', ' + value[18] + 'h:' + value[19] + 'm ' + value[20]/2 + '°C' +
', ' + value[21] + 'h:' + value[22] + 'm ' + value[23]/2 + '°C ',
sunday: ' ' + value[24] + 'h:' + value[25] + 'm ' + value[26]/2 + '°C' +
', ' + value[27] + 'h:' + value[28] + 'm ' + value[29]/2 + '°C' +
', ' + value[30] + 'h:' + value[31] + 'm ' + value[32]/2 + '°C' +
', ' + value[33] + 'h:' + value[34] + 'm ' + value[35]/2 + '°C ',
},
};
case tuya.dataPoints.moesSboostHeatingCountdownTimeSet:
return {boost_time_set: (value)};
case tuya.dataPoints.moesSvalvePosition:
return {position: value};
case tuya.dataPoints.moesScompensationTempSet:
return {local_temperature_calibration: value};
case tuya.dataPoints.moesSecoMode:
return {eco_mode: value ? 'ON' : 'OFF'};
case tuya.dataPoints.moesSecoModeTempSet:
return {eco_temperature: value};
case tuya.dataPoints.moesSmaxTempSet:
return {max_temperature: value};
case tuya.dataPoints.moesSminTempSet:
return {min_temperature: value};
default:
meta.logger.warn(`zigbee-herdsman-converters:moesS_thermostat: NOT RECOGNIZED DP #${
dp} with data ${JSON.stringify(msg.data)}`);
}
},
},
tuya_air_quality: {
cluster: 'manuSpecificTuya',
type: ['commandSetDataResponse', 'commandGetData'],
Expand Down
77 changes: 77 additions & 0 deletions converters/toZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,83 @@ const converters = {
await tuya.sendDataPointBool(entity, tuya.dataPoints.state, value === 'heat');
},
},
moesS_thermostat_system_mode: {
key: ['preset'],
convertSet: async (entity, key, value, meta) => {
const lookup = {'programming': 0, 'manual': 1, 'temporary_manual': 2, 'holiday': 3};
await tuya.sendDataPointEnum(entity, tuya.dataPoints.moesSsystemMode, lookup[value]);
},
},
moesS_thermostat_current_heating_setpoint: {
key: ['current_heating_setpoint'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSheatingSetpoint, value);
},
},
moesS_thermostat_boost_heating: {
key: ['boost_heating'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointBool(entity, tuya.dataPoints.moesSboostHeating, value === 'OFF');
},
},
moesS_thermostat_boost_heating_countdown: {
key: ['boost_heating_countdown'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSboostHeatingCountdown, value);
},
},
moesS_thermostat_window_detection: {
key: ['window_detection'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointRaw(entity, tuya.dataPoints.moesSwindowDetection, [value === 'ON' ? 1 : 0]);
},
},
moesS_thermostat_child_lock: {
key: ['child_lock'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointBool(entity, tuya.dataPoints.moesSchildLock, value === 'LOCK');
},
},
moesS_thermostat_boostHeatingCountdownTimeSet: {
key: ['boost_time_set'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSboostHeatingCountdownTimeSet, value);
},
},
moesS_thermostat_temperature_calibration: {
key: ['local_temperature_calibration'],
convertSet: async (entity, key, value, meta) => {
let temp = Math.round(value * 1);
if (temp < 0) {
temp = 0xFFFFFFFF + temp + 1;
}
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesScompensationTempSet, temp);
},
},
moesS_thermostat_moesSecoMode: {
key: ['eco_mode'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointBool(entity, tuya.dataPoints.moesSecoMode, value === 'OFF');
},
},
moesS_thermostat_eco_temperature: {
key: ['eco_temperature'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointEnum(entity, tuya.dataPoints.moesSecoModeTempSet, value);
},
},
moesS_thermostat_max_temperature: {
key: ['max_temperature'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSmaxTempSet, value);
},
},
moesS_thermostat_min_temperature: {
key: ['min_temperature'],
convertSet: async (entity, key, value, meta) => {
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSminTempSet, value);
},
},
hgkg_thermostat_standby: {
key: ['system_mode'],
convertSet: async (entity, key, value, meta) => {
Expand Down
36 changes: 36 additions & 0 deletions devices/moes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const exposes = require('../lib/exposes');
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
const tz = require('../converters/toZigbee');
const ota = require('../lib/ota');
const tuya = require('../lib/tuya');
const reporting = require('../lib/reporting');
const extend = require('../lib/extend');
Expand Down Expand Up @@ -151,4 +152,39 @@ module.exports = [
toZigbee: [],
exposes: [e.battery(), e.illuminance(), e.illuminance_lux().withUnit('lx'), e.humidity(), e.temperature()],
},
{
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_b6wax7g0'}],
model: 'BRT-100-TRV',
vendor: 'Moes',
description: 'Thermostatic radiator valve',
ota: ota.zigbeeOTA,
onEvent: tuya.onEventSetLocalTime,
fromZigbee: [fz.ignore_basic_report, fz.ignore_tuya_set_time, fz.moesS_thermostat],
toZigbee: [tz.moesS_thermostat_current_heating_setpoint, tz.moesS_thermostat_child_lock,
tz.moesS_thermostat_window_detection, tz.moesS_thermostat_temperature_calibration,
tz.moesS_thermostat_boost_heating_countdown, tz.moesS_thermostat_system_mode,
tz.moesS_thermostat_boost_heating, tz.moesS_thermostat_boostHeatingCountdownTimeSet,
tz.moesS_thermostat_eco_temperature, tz.moesS_thermostat_max_temperature,
tz.moesS_thermostat_min_temperature, tz.moesS_thermostat_moesSecoMode],
exposes: [
e.battery(), e.child_lock(), e.eco_temperature(), e.max_temperature(), e.min_temperature(), e.window_detection(), e.position(),
exposes.climate()
.withLocalTemperature(ea.STATE).withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
.withLocalTemperatureCalibration(ea.STATE_SET).withPreset(['programming', 'manual', 'temporary_manual', 'holiday'],
'MANUAL MODE ☝ - In this mode, the device executes manual temperature setting. '+
'When the set temperature is lower than the "minimum temperature", the valve is closed (forced closed). ' +
'PROGRAMMING MODE ⏱ - In this mode, the device executes a preset week programming temperature time and temperature. ' +
'HOLIDAY MODE ⛱ - In this mode, for example, the vacation mode is set for 10 days and the temperature is set' +
'to 15 degrees Celsius. After 10 days, the device will automatically switch to programming mode. ' +
'TEMPORARY MANUAL MODE - In this mode, ☝ icon will flash. At this time, the device executes the manually set ' +
'temperature and returns to the weekly programming mode in the next time period. '),
exposes.enum('programming_mode', ea.STATE).withDescription('PROGRAMMING MODE ⏱ - In this mode, the device executes a ' +
'preset week programming temperature time and temperature. '),
exposes.binary('boost_heating', ea.STATE_SET).withDescription('Boost Heating: press and hold "+" for 3 seconds, ' +
'the device will enter the boost heating mode, and the ▷╵◁ will flash. The countdown will be displayed in the APP'),
exposes.numeric('boost_heating_countdown', ea.STATE_SET).withUnit('min').withDescription('Countdown in minutes'),
exposes.numeric('boost_time_set', ea.STATE_SET).withUnit('second')
.withDescription('Boost Time Setting 100 sec - 900 sec, (default = 300 sec)'),
exposes.binary('eco_mode', ea.STATE_SET).withDescription('ECO mode')],
},
];
4 changes: 2 additions & 2 deletions lib/exposes.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,9 @@ class Climate extends Base {
return this;
}

withPreset(modes) {
withPreset(modes, description='Mode of this device (similar to system_mode)') {
assert(!this.endpoint, 'Cannot add feature after adding endpoint');
this.features.push(new Enum('preset', access.STATE_SET, modes).withDescription('Mode of this device (similar to system_mode)'));
this.features.push(new Enum('preset', access.STATE_SET, modes).withDescription(description));
return this;
}

Expand Down
19 changes: 19 additions & 0 deletions lib/tuya.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,25 @@ const dataPoints = {
moesSensor: 43,
moesSchedule: 101,
etopErrorStatus: 13,
// MoesS Thermostat
moesSsystemMode: 1,
moesSheatingSetpoint: 2,
moesSlocalTemp: 3,
moesSboostHeating: 4,
moesSboostHeatingCountdown: 5,
moesSreset: 7,
moesSwindowDetectionFunktion_A2: 8,
moesSwindowDetection: 9,
moesSchildLock: 13,
moesSbattery: 14,
moesSschedule: 101,
moesSvalvePosition: 104,
moesSboostHeatingCountdownTimeSet: 103,
moesScompensationTempSet: 105,
moesSecoMode: 106,
moesSecoModeTempSet: 107,
moesSmaxTempSet: 108,
moesSminTempSet: 109,
// Neo T&H
neoPowerType: 101,
neoMelody: 102,
Expand Down

0 comments on commit 5b524ea

Please sign in to comment.