From 72faf7756bb94d095cc3dcb26bc8b5f890e9cb0e Mon Sep 17 00:00:00 2001 From: Doable Date: Wed, 4 Dec 2024 22:38:52 +0100 Subject: [PATCH 1/3] Fix MAZDA TR-M2Z Get system mode with preset enabled --- .prettierignore | 3 +- src/devices/mazda.ts | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/devices/mazda.ts diff --git a/.prettierignore b/.prettierignore index 7e70d52abd2cf..b9bcfcb5e1e82 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ pnpm-lock.yaml -CHANGELOG.md \ No newline at end of file +CHANGELOG.md +README.md \ No newline at end of file diff --git a/src/devices/mazda.ts b/src/devices/mazda.ts new file mode 100644 index 0000000000000..9ad9e3a811df2 --- /dev/null +++ b/src/devices/mazda.ts @@ -0,0 +1,111 @@ +import * as exposes from '../lib/exposes'; +import * as tuya from '../lib/tuya'; +import {DefinitionWithExtend} from '../lib/types'; + +const e = exposes.presets; +const ea = exposes.access; + +const definitions: DefinitionWithExtend[] = [ + { + fingerprint: [ + { + modelID: 'TS0601', + manufacturerName: '_TZE284_k6rdmisz', + }, + { + modelID: 'TS0601', + manufacturerName: '_TZE204_k6rdmisz', + }, + ], + model: 'TR-M2Z', + vendor: 'MAZDA', + description: 'Thermostatic radiator valve', + fromZigbee: [tuya.fz.datapoints], + toZigbee: [tuya.tz.datapoints], + onEvent: tuya.onEventSetTime, + configure: tuya.configureMagicPacket, + exposes: [ + e.battery(), + e.child_lock(), + e.temperature(), + e.window_detection(), + tuya.exposes.frostProtection(), + e.binary('alarm_switch', ea.STATE, 'ON', 'OFF').withDescription('Thermostat in error state'), + e.comfort_temperature().withValueMin(5).withValueMax(35).withDescription('Comfort mode temperature'), + e.eco_temperature().withValueMin(5).withValueMax(35).withDescription('Eco mode temperature'), + e.holiday_temperature().withValueMin(5).withValueMax(35).withDescription('Holiday mode temperature'), + e + .numeric('temperature_sensitivity', ea.STATE_SET) + .withUnit('°C') + .withValueMin(0.5) + .withValueMax(5) + .withValueStep(0.5) + .withDescription('Temperature sensitivity'), + e + .climate() + .withLocalTemperature(ea.STATE) + .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET) + .withPreset(['manual', 'schedule', 'eco', 'comfort', 'frost_protection', 'holiday', 'off']) + .withRunningState(['idle', 'heat'], ea.STATE) + .withSystemMode(['off', 'heat'], ea.STATE, 'Only for Homeassistant') + .withLocalTemperatureCalibration(-9.5, 9.5, 0.5, ea.STATE_SET), + ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'), + ], + meta: { + tuyaDatapoints: [ + [ + 2, + 'preset', + tuya.valueConverterBasic.lookup({ + manual: tuya.enum(0), + schedule: tuya.enum(1), + eco: tuya.enum(2), + comfort: tuya.enum(3), + frost_protection: tuya.enum(4), + holiday: tuya.enum(5), + off: tuya.enum(6), + }), + ], + [ + 2, + 'system_mode', + { + from: (v) => { + return v === tuya.enum(6) ? 'off' : 'heat'; + }, + to: (v) => { + // By default switching to "heat" will activate schedule mode on Homeassistant + return v === 'off' ? tuya.enum(6) : tuya.enum(1); + }, + }, + ], + [3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})], + [3, 'system_mode', tuya.valueConverterBasic.lookup({heat: tuya.enum(1), off: tuya.enum(0)})], + [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10], + [5, 'local_temperature', tuya.valueConverter.divideBy10], + [6, 'battery', tuya.valueConverter.raw], + [7, 'child_lock', tuya.valueConverter.lockUnlock], + [103, 'eco_temperature', tuya.valueConverter.divideBy10], + [104, 'comfort_temperature', tuya.valueConverter.divideBy10], + [105, 'frost_temperature', tuya.valueConverter.divideBy10], + [102, 'temperature_sensitivity', tuya.valueConverter.divideBy10], + [21, 'holiday_temperature', tuya.valueConverter.divideBy10], + [15, 'window', tuya.valueConverterBasic.lookup({OPEN: 1, CLOSE: 0})], + [14, 'window_detection', tuya.valueConverter.onOff], + [35, 'alarm_switch', tuya.valueConverter.onOff], + [36, 'frost_protection', tuya.valueConverter.onOff], + [28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1, 6)], + [29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2, 6)], + [30, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3, 6)], + [31, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4, 6)], + [32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5, 6)], + [33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6, 6)], + [34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7, 6)], + [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1], + ], + }, + }, +]; + +export default definitions; +module.exports = definitions; From aa33c500d9ea2b62e6260957e73fd5b90e5e56bf Mon Sep 17 00:00:00 2001 From: Doable Date: Wed, 4 Dec 2024 23:20:28 +0100 Subject: [PATCH 2/3] I don't know why README.md keeps prettyprinting itself --- .prettierignore | 3 +-- README.md | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.prettierignore b/.prettierignore index b9bcfcb5e1e82..7e70d52abd2cf 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,2 @@ pnpm-lock.yaml -CHANGELOG.md -README.md \ No newline at end of file +CHANGELOG.md \ No newline at end of file diff --git a/README.md b/README.md index fd309afeac8a7..14b04f7af3f61 100644 --- a/README.md +++ b/README.md @@ -8,24 +8,24 @@ Collection of device converters to be used with zigbee-herdsman. 20.0.0 -- A toZigbee converter is now allowed to not define any `key`, in this case the converter should be used for any key. +- A toZigbee converter is now allowed to not define any `key`, in this case the converter should be used for any key. 19.0.0 -- Legacy extend was removed +- Legacy extend was removed 18.0.0 -- After converting a message with a fromZigbee converter, `postProcessConvertedFromZigbeeMessage` should be called now (for applying calibration/precision) +- After converting a message with a fromZigbee converter, `postProcessConvertedFromZigbeeMessage` should be called now (for applying calibration/precision) 17.0.0 -- Various methods in `index.ts` are now async and return a `Promise` +- Various methods in `index.ts` are now async and return a `Promise` 15.0.0 -- OTA `isUpdateAvailable` now returns an object instead of a boolean (e.g. `{available: true, currentFileVersion: 120, otaFileVersion: 125}`) -- OTA `updateToLatest` now returns a number (`fileVersion` of the new OTA) instead of a void +- OTA `isUpdateAvailable` now returns an object instead of a boolean (e.g. `{available: true, currentFileVersion: 120, otaFileVersion: 125}`) +- OTA `updateToLatest` now returns a number (`fileVersion` of the new OTA) instead of a void ## Contributing From c60efc48374a79bf6fcf9bfb176475a9c8d6cae1 Mon Sep 17 00:00:00 2001 From: Nopraz <12595433+Nopraz@users.noreply.github.com> Date: Wed, 4 Dec 2024 23:31:15 +0100 Subject: [PATCH 3/3] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 14b04f7af3f61..fd309afeac8a7 100644 --- a/README.md +++ b/README.md @@ -8,24 +8,24 @@ Collection of device converters to be used with zigbee-herdsman. 20.0.0 -- A toZigbee converter is now allowed to not define any `key`, in this case the converter should be used for any key. +- A toZigbee converter is now allowed to not define any `key`, in this case the converter should be used for any key. 19.0.0 -- Legacy extend was removed +- Legacy extend was removed 18.0.0 -- After converting a message with a fromZigbee converter, `postProcessConvertedFromZigbeeMessage` should be called now (for applying calibration/precision) +- After converting a message with a fromZigbee converter, `postProcessConvertedFromZigbeeMessage` should be called now (for applying calibration/precision) 17.0.0 -- Various methods in `index.ts` are now async and return a `Promise` +- Various methods in `index.ts` are now async and return a `Promise` 15.0.0 -- OTA `isUpdateAvailable` now returns an object instead of a boolean (e.g. `{available: true, currentFileVersion: 120, otaFileVersion: 125}`) -- OTA `updateToLatest` now returns a number (`fileVersion` of the new OTA) instead of a void +- OTA `isUpdateAvailable` now returns an object instead of a boolean (e.g. `{available: true, currentFileVersion: 120, otaFileVersion: 125}`) +- OTA `updateToLatest` now returns a number (`fileVersion` of the new OTA) instead of a void ## Contributing