Skip to content

Commit 437e0e2

Browse files
svhelgeSvhelgeCopilot
authored
fix: Namron thermostat: refactor converters to use typed cluster definitions (#12117)
Co-authored-by: Svhelge <svein.helge@hoydal.net> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent c8a25b3 commit 437e0e2

5 files changed

Lines changed: 977 additions & 436 deletions

File tree

src/converters/fromZigbee.ts

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,79 +1974,6 @@ export const power_source: Fz.Converter<"genBasic", undefined, ["attributeReport
19741974
// #endregion
19751975

19761976
// #region Non-generic converters
1977-
export const namron_thermostat: Fz.Converter<"hvacThermostat", undefined, ["attributeReport", "readResponse"]> = {
1978-
cluster: "hvacThermostat",
1979-
type: ["attributeReport", "readResponse"],
1980-
convert: (model, msg, publish, options, meta) => {
1981-
const result: KeyValueAny = {};
1982-
const data = msg.data;
1983-
if (data[0x1000] !== undefined) {
1984-
// Display brightness
1985-
const lookup: KeyValueAny = {0: "low", 1: "mid", 2: "high"};
1986-
result.lcd_brightness = lookup[data[0x1000] as number];
1987-
}
1988-
if (data[0x1001] !== undefined) {
1989-
// Button vibration level
1990-
const lookup: KeyValueAny = {0: "off", 1: "low", 2: "high"};
1991-
result.button_vibration_level = lookup[data[0x1001] as number];
1992-
}
1993-
if (data[0x1002] !== undefined) {
1994-
// Floor sensor type
1995-
const lookup: KeyValueAny = {1: "10k", 2: "15k", 3: "50k", 4: "100k", 5: "12k"};
1996-
result.floor_sensor_type = lookup[data[0x1002] as number];
1997-
}
1998-
if (data[0x1003] !== undefined) {
1999-
// Sensor
2000-
const lookup: KeyValueAny = {0: "air", 1: "floor", 2: "both"};
2001-
result.sensor = lookup[data[0x1003] as number];
2002-
}
2003-
if (data[0x1004] !== undefined) {
2004-
// PowerUpStatus
2005-
const lookup: KeyValueAny = {0: "default", 1: "last_status"};
2006-
result.powerup_status = lookup[data[0x1004] as number];
2007-
}
2008-
if (data[0x1005] !== undefined) {
2009-
// FloorSensorCalibration
2010-
result.floor_sensor_calibration = precisionRound(data[0x1005] as number, 2) / 10;
2011-
}
2012-
if (data[0x1006] !== undefined) {
2013-
// DryTime
2014-
result.dry_time = data[0x1006];
2015-
}
2016-
if (data[0x1007] !== undefined) {
2017-
// ModeAfterDry
2018-
const lookup: KeyValueAny = {0: "off", 1: "manual", 2: "auto", 3: "away"};
2019-
result.mode_after_dry = lookup[data[0x1007] as number];
2020-
}
2021-
if (data[0x1008] !== undefined) {
2022-
// TemperatureDisplay
2023-
const lookup: KeyValueAny = {0: "room", 1: "floor"};
2024-
result.temperature_display = lookup[data[0x1008] as number];
2025-
}
2026-
if (data[0x1009] !== undefined) {
2027-
// WindowOpenCheck
2028-
result.window_open_check = (data[0x1009] as number) / 2;
2029-
}
2030-
if (data[0x100a] !== undefined) {
2031-
// Hysterersis
2032-
result.hysterersis = precisionRound(data[0x100a] as number, 2) / 10;
2033-
}
2034-
if (data[0x100b] !== undefined) {
2035-
// DisplayAutoOffEnable
2036-
result.display_auto_off_enabled = data[0x100b] ? "enabled" : "disabled";
2037-
}
2038-
if (data[0x2001] !== undefined) {
2039-
// AlarmAirTempOverValue
2040-
result.alarm_airtemp_overvalue = data[0x2001];
2041-
}
2042-
if (data[0x2002] !== undefined) {
2043-
// Away Mode Set
2044-
result.away_mode = data[0x2002] ? "ON" : "OFF";
2045-
}
2046-
2047-
return result;
2048-
},
2049-
};
20501977
export const namron_hvac_user_interface: Fz.Converter<"hvacUserInterfaceCfg", undefined, ["attributeReport", "readResponse"]> = {
20511978
cluster: "hvacUserInterfaceCfg",
20521979
type: ["attributeReport", "readResponse"],

src/converters/toZigbee.ts

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {determineEndpoint} from "../lib/utils";
1313

1414
const NS = "zhc:tz";
1515
const manufacturerOptions = {
16-
sunricher: {manufacturerCode: Zcl.ManufacturerCode.SHENZHEN_SUNRICHER_TECHNOLOGY_LTD},
1716
lumi: {manufacturerCode: Zcl.ManufacturerCode.LUMI_UNITED_TECHOLOGY_LTD_SHENZHEN, disableDefaultResponse: true},
1817
eurotronic: {manufacturerCode: Zcl.ManufacturerCode.NXP_SEMICONDUCTORS},
1918
hue: {manufacturerCode: Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V},
@@ -2635,129 +2634,6 @@ export const ZMCSW032D_cover_position: Tz.Converter = {
26352634
await entity.read("closuresWindowCovering", [isPosition ? "currentPositionLiftPercentage" : "currentPositionTiltPercentage"]);
26362635
},
26372636
};
2638-
export const namron_thermostat: Tz.Converter = {
2639-
key: [
2640-
"lcd_brightness",
2641-
"button_vibration_level",
2642-
"floor_sensor_type",
2643-
"sensor",
2644-
"powerup_status",
2645-
"floor_sensor_calibration",
2646-
"dry_time",
2647-
"mode_after_dry",
2648-
"temperature_display",
2649-
"window_open_check",
2650-
"hysterersis",
2651-
"display_auto_off_enabled",
2652-
"alarm_airtemp_overvalue",
2653-
"away_mode",
2654-
],
2655-
convertSet: async (entity, key, value, meta) => {
2656-
if (key === "lcd_brightness") {
2657-
const lookup = {low: 0, mid: 1, high: 2};
2658-
const payload = {4096: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2659-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2660-
} else if (key === "button_vibration_level") {
2661-
const lookup = {off: 0, low: 1, high: 2};
2662-
const payload = {4097: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2663-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2664-
} else if (key === "floor_sensor_type") {
2665-
const lookup = {"10k": 1, "15k": 2, "50k": 3, "100k": 4, "12k": 5};
2666-
const payload = {4098: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2667-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2668-
} else if (key === "sensor") {
2669-
const lookup = {air: 0, floor: 1, both: 2};
2670-
const payload = {4099: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2671-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2672-
} else if (key === "powerup_status") {
2673-
const lookup = {default: 0, last_status: 1};
2674-
const payload = {4100: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2675-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2676-
} else if (key === "floor_sensor_calibration") {
2677-
utils.assertNumber(value);
2678-
const payload = {4101: {value: Math.round(value * 10), type: 0x28}}; // INT8S
2679-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2680-
} else if (key === "dry_time") {
2681-
const payload = {4102: {value: value, type: 0x20}}; // INT8U
2682-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2683-
} else if (key === "mode_after_dry") {
2684-
const lookup = {off: 0, manual: 1, auto: 2, away: 3};
2685-
const payload = {4103: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2686-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2687-
} else if (key === "temperature_display") {
2688-
const lookup = {room: 0, floor: 1};
2689-
const payload = {4104: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2690-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2691-
} else if (key === "window_open_check") {
2692-
utils.assertNumber(value);
2693-
const payload = {4105: {value: value * 2, type: 0x20}};
2694-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2695-
} else if (key === "hysterersis") {
2696-
utils.assertNumber(value);
2697-
const payload = {4106: {value: value * 10, type: 0x20}};
2698-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2699-
} else if (key === "display_auto_off_enabled") {
2700-
const lookup = {disabled: 0, enabled: 1};
2701-
const payload = {4107: {value: utils.getFromLookup(value, lookup), type: Zcl.DataType.ENUM8}};
2702-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2703-
} else if (key === "alarm_airtemp_overvalue") {
2704-
const payload = {8193: {value: value, type: 0x20}};
2705-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2706-
} else if (key === "away_mode") {
2707-
const payload = {8194: {value: Number(value === "ON"), type: 0x30}};
2708-
await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2709-
}
2710-
},
2711-
convertGet: async (entity, key, meta) => {
2712-
switch (key) {
2713-
case "lcd_brightness":
2714-
await entity.read("hvacThermostat", [0x1000], manufacturerOptions.sunricher);
2715-
break;
2716-
case "button_vibration_level":
2717-
await entity.read("hvacThermostat", [0x1001], manufacturerOptions.sunricher);
2718-
break;
2719-
case "floor_sensor_type":
2720-
await entity.read("hvacThermostat", [0x1002], manufacturerOptions.sunricher);
2721-
break;
2722-
case "sensor":
2723-
await entity.read("hvacThermostat", [0x1003], manufacturerOptions.sunricher);
2724-
break;
2725-
case "powerup_status":
2726-
await entity.read("hvacThermostat", [0x1004], manufacturerOptions.sunricher);
2727-
break;
2728-
case "floor_sensor_calibration":
2729-
await entity.read("hvacThermostat", [0x1005], manufacturerOptions.sunricher);
2730-
break;
2731-
case "dry_time":
2732-
await entity.read("hvacThermostat", [0x1006], manufacturerOptions.sunricher);
2733-
break;
2734-
case "mode_after_dry":
2735-
await entity.read("hvacThermostat", [0x1007], manufacturerOptions.sunricher);
2736-
break;
2737-
case "temperature_display":
2738-
await entity.read("hvacThermostat", [0x1008], manufacturerOptions.sunricher);
2739-
break;
2740-
case "window_open_check":
2741-
await entity.read("hvacThermostat", [0x1009], manufacturerOptions.sunricher);
2742-
break;
2743-
case "hysterersis":
2744-
await entity.read("hvacThermostat", [0x100a], manufacturerOptions.sunricher);
2745-
break;
2746-
case "display_auto_off_enabled":
2747-
await entity.read("hvacThermostat", [0x100b], manufacturerOptions.sunricher);
2748-
break;
2749-
case "alarm_airtemp_overvalue":
2750-
await entity.read("hvacThermostat", [0x2001], manufacturerOptions.sunricher);
2751-
break;
2752-
case "away_mode":
2753-
await entity.read("hvacThermostat", [0x2002], manufacturerOptions.sunricher);
2754-
break;
2755-
2756-
default: // Unknown key
2757-
throw new Error(`Unhandled key toZigbee.namron_thermostat.convertGet ${key}`);
2758-
}
2759-
},
2760-
};
27612637
export const namron_thermostat_child_lock: Tz.Converter = {
27622638
key: ["child_lock"],
27632639
convertSet: async (entity, key, value, meta) => {

0 commit comments

Comments
 (0)