zigbee-herdsman-converters
Version:
Collection of device converters to be used with zigbee-herdsman
1,062 lines (1,061 loc) • 152 kB
JavaScript
"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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.definitions = void 0;
const zigbee_herdsman_1 = require("zigbee-herdsman");
const fz = __importStar(require("../converters/fromZigbee"));
const tz = __importStar(require("../converters/toZigbee"));
const constants = __importStar(require("../lib/constants"));
const exposes = __importStar(require("../lib/exposes"));
const logger_1 = require("../lib/logger");
const m = __importStar(require("../lib/modernExtend"));
const reporting = __importStar(require("../lib/reporting"));
const globalStore = __importStar(require("../lib/store"));
const utils = __importStar(require("../lib/utils"));
const utils_1 = require("../lib/utils");
const stelpro = __importStar(require("./stelpro"));
const e = exposes.presets;
const ea = exposes.access;
const NS = "zhc:schneider_electric";
function indicatorMode(endpoint) {
let description = "Set Indicator Mode.";
if (endpoint) {
description = `Set Indicator Mode for ${endpoint} switch.`;
}
return m.enumLookup({
name: "indicator_mode",
lookup: {
reverse_with_load: 2,
consistent_with_load: 0,
always_off: 3,
always_on: 1,
},
cluster: "manuSpecificSchneiderLightSwitchConfiguration",
attribute: "ledIndication",
description: description,
endpointName: endpoint,
});
}
function socketIndicatorMode() {
return m.enumLookup({
name: "indicator_mode",
lookup: {
reverse_with_load: 0,
consistent_with_load: 1,
always_off: 2,
always_on: 3,
},
cluster: "manuSpecificSchneiderFanSwitchConfiguration",
attribute: "ledIndication",
description: "Set indicator mode",
});
}
function evlinkIndicatorMode() {
return m.enumLookup({
name: "indicator_mode",
lookup: {
default: 1,
temporary: 5,
},
cluster: "manuSpecificSchneiderFanSwitchConfiguration",
attribute: "ledIndication",
description: "Set indicator mode",
});
}
function fanIndicatorMode() {
const description = "Set Indicator Mode.";
return m.enumLookup({
name: "indicator_mode",
lookup: {
always_on: 3,
on_with_timeout_but_as_locator: 4,
on_with_timeout: 5,
},
cluster: "manuSpecificSchneiderFanSwitchConfiguration",
attribute: "ledIndication",
description: description,
});
}
function fanIndicatorOrientation() {
const description = "Set Indicator Orientation.";
return m.enumLookup({
name: "indicator_orientation",
lookup: {
horizontal_left: 2,
horizontal_right: 0,
vertical_top: 3,
vertical_bottom: 1,
},
cluster: "manuSpecificSchneiderFanSwitchConfiguration",
attribute: "ledOrientation",
description: description,
});
}
function switchActions(endpoint) {
let description = "Set Switch Action.";
if (endpoint) {
description = `Set Switch Action for ${endpoint} Button.`;
}
return m.enumLookup({
name: "switch_actions",
lookup: {
light: 0,
light_opposite: 254,
dimmer: 1,
dimmer_opposite: 253,
standard_shutter: 2,
standard_shutter_opposite: 252,
schneider_shutter: 3,
schneider_shutter_opposite: 251,
scene: 4,
toggle_light: 5,
toggle_dimmer: 6,
alternate_light: 7,
alternate_dimmer: 8,
not_used: 127,
},
cluster: "manuSpecificSchneiderLightSwitchConfiguration",
attribute: "switchActions",
description: description,
endpointName: endpoint,
});
}
const schneiderElectricExtend = {
addVisaConfigurationCluster: (enumDataType) => m.deviceAddCustomCluster("visaConfiguration", {
name: "visaConfiguration",
ID: 0xfc04,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
attributes: {
indicatorLuminanceLevel: { name: "indicatorLuminanceLevel", ID: 0x0000, type: enumDataType, write: true },
indicatorColor: { name: "indicatorColor", ID: 0x0001, type: enumDataType, write: true },
indicatorMode: { name: "indicatorMode", ID: 0x0002, type: enumDataType, write: true },
motorTypeChannel1: { name: "motorTypeChannel1", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
motorTypeChannel2: { name: "motorTypeChannel2", ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
curtainStatusChannel1: { name: "curtainStatusChannel1", ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
curtainStatusChannel2: { name: "curtainStatusChannel2", ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
key1EventNotification: { name: "key1EventNotification", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
key2EventNotification: { name: "key2EventNotification", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
key3EventNotification: { name: "key3EventNotification", ID: 0x0022, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
key4EventNotification: { name: "key4EventNotification", ID: 0x0023, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
},
commands: {},
commandsResponse: {},
}),
visaConfigIndicatorLuminanceLevel: () => {
return m.enumLookup({
name: "indicator_luminance_level",
lookup: {
"100": 0,
"80": 1,
"60": 2,
"40": 3,
"20": 4,
"0": 5,
},
cluster: "visaConfiguration",
attribute: "indicatorLuminanceLevel",
description: "Set indicator luminance Level",
});
},
visaConfigIndicatorColor: () => {
return m.enumLookup({
name: "indicator_color",
lookup: {
white: 0,
blue: 1,
},
cluster: "visaConfiguration",
attribute: "indicatorColor",
description: "Set indicator color",
});
},
visaIndicatorMode: ([reverseWithLoad, consistentWithLoad, alwaysOff, alwaysOn]) => {
return m.enumLookup({
name: "indicator_mode",
lookup: {
reverse_with_load: reverseWithLoad,
consistent_with_load: consistentWithLoad,
always_off: alwaysOff,
always_on: alwaysOn,
},
cluster: "visaConfiguration",
attribute: "indicatorMode",
description: "Set indicator mode for switch",
});
},
visaConfigMotorType: (channel) => {
// TODO: was defaulting `motorTypeChannel` which is not part of the custom cluster
const attribute = `motorTypeChannel${channel}`;
const description = `Set motor type for channel ${channel || ""}`;
return m.enumLookup({
name: `motor_type${channel ? `_${channel}` : ""}`,
lookup: {
ac_motor: 0,
pulse_motor: 1,
},
cluster: "visaConfiguration",
attribute: attribute,
description: description,
});
},
visaConfigCurtainStatus: (channel) => {
// TODO: was defaulting `motorTypeChannel` which is not part of the custom cluster
const attribute = `curtainStatusChannel${channel}`;
const description = `Set curtain status for channel ${channel}`;
return m.enumLookup({
access: "STATE",
name: `curtain_status${channel ? `_${channel}` : ""}`,
lookup: {
stop: 0,
opening: 1,
closing: 2,
},
cluster: "visaConfiguration",
attribute: attribute,
description: description,
});
},
visaWiserCurtain: (endpointNames) => {
return {
isModernExtend: true,
fromZigbee: [
{
cluster: "genLevelCtrl",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
const onOffTransitionTime = Number(msg.data.onOffTransitionTime) / 10;
const currentLevel = utils.mapNumberRange(Number(msg.data.currentLevel), 0, 255, 0, 100);
const transition = (0, utils_1.postfixWithEndpointName)("transition", msg, model, meta);
const position = (0, utils_1.postfixWithEndpointName)("position", msg, model, meta);
return {
[transition]: onOffTransitionTime,
[position]: currentLevel,
};
},
},
],
toZigbee: [
{
key: ["transition", "position"],
convertGet: async (entity, key, meta) => {
await entity.read("genLevelCtrl", ["onOffTransitionTime", "currentLevel"]);
},
convertSet: async (entity, key, value, meta) => {
if (key === "transition") {
await entity.write("genLevelCtrl", { onOffTransitionTime: +value * 10 }, utils.getOptions(meta.mapped, entity));
}
else if (key === "position") {
await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(Number(value), 0, 100, 0, 255), transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
}
},
},
{
key: ["state"],
convertSet: async (entity, key, value, meta) => {
if (value === "OPEN") {
await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
}
else if (value === "CLOSE") {
await entity.command("genOnOff", "off", {}, utils.getOptions(meta.mapped, entity));
}
else if (value === "STOP") {
await entity.command("genLevelCtrl", "stop", { optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
}
},
},
],
exposes: [
...endpointNames.map((endpointName) => e.cover_position().withDescription("State of the curtain").withEndpoint(endpointName)),
...endpointNames.map((endpointName) => e
.numeric("transition", ea.ALL)
.withValueMin(0)
.withValueMax(300)
.withUnit("s")
.withDescription("Transition time in seconds")
.withEndpoint(endpointName)),
],
};
},
visaKeyEventNotification: (key) => {
return {
isModernExtend: true,
fromZigbee: [
{
cluster: "visaConfiguration",
type: ["attributeReport"],
convert: (model, msg, publish, options, meta) => {
for (const key of ["1", "2", "3", "4"]) {
const zigbeeKey = `key${key}EventNotification`;
if (Object.hasOwn(msg.data, zigbeeKey)) {
return { action: `scene_${key}` };
}
}
},
},
],
};
},
dimmingMode: () => {
const extend = m.enumLookup({
name: "dimmer_mode",
lookup: {
Auto: 0,
"RL-LED": 3,
},
cluster: "lightingBallastCfg",
attribute: "wiserControlMode",
description: "Auto detects the correct mode for the ballast. RL-LED may have improved dimming quality for LEDs.",
entityCategory: "config",
});
extend.configure.push(m.setupConfigureForReading("lightingBallastCfg", ["wiserControlMode"]));
return extend;
},
addOccupancyConfigurationCluster: () => m.deviceAddCustomCluster("occupancyConfiguration", {
name: "occupancyConfiguration",
ID: 0xff19,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
attributes: {
ambienceLightThreshold: { name: "ambienceLightThreshold", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff },
occupancyActions: { name: "occupancyActions", ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
unoccupiedLevelDflt: { name: "unoccupiedLevelDflt", ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
unoccupiedLevel: { name: "unoccupiedLevel", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
},
commands: {},
commandsResponse: {},
}),
occupancyConfiguration: () => {
const extend = m.enumLookup({
name: "occupancy_sensitivity",
lookup: {
Low: 50,
Medium: 75,
High: 100,
},
cluster: "msOccupancySensing",
attribute: { ID: 0xe003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
zigbeeCommandOptions: {
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
description: "Sensitivity of the occupancy sensor",
entityCategory: "config",
});
const luxScale = (value, type) => {
if (type === "from") {
return Math.round(10 ** ((value - 1) / 10000));
}
return Math.round(10000 * Math.log10(value) + 1);
};
const luxThresholdExtend = m.numeric({
name: "ambience_light_threshold",
cluster: "occupancyConfiguration",
attribute: "ambienceLightThreshold",
reporting: { min: "10_SECONDS", max: "1_HOUR", change: 5 },
description: "Threshold above which occupancy will not trigger the light switch.",
unit: "lx",
scale: luxScale,
entityCategory: "config",
valueMin: 1,
valueMax: 2000,
});
extend.fromZigbee.push(...luxThresholdExtend.fromZigbee);
extend.toZigbee.push(...luxThresholdExtend.toZigbee);
extend.exposes.push(...luxThresholdExtend.exposes);
extend.configure.push(m.setupConfigureForReading("occupancyConfiguration", ["ambienceLightThreshold"]));
return extend;
},
thermostatWithPower: (options) => {
const extend = m.thermostat(options);
const climateExpose = extend.exposes.find((exp) => typeof exp !== "function" && "type" in exp && exp.type === "climate");
if (climateExpose) {
climateExpose.withRunningState(["idle", "heat"]);
const runningStateFeature = climateExpose.features.find((f) => typeof f !== "function" && "name" in f && f.name === "running_state");
if (runningStateFeature) {
runningStateFeature.withDescription("Running state based on power draw (>10W)");
}
}
extend.fromZigbee.push({
cluster: "seMetering",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
if ("instantaneousDemand" in msg.data) {
const w = Math.max(0, Number(msg.data.instantaneousDemand));
return { running_state: w > 10 ? "heat" : "idle" };
}
},
});
return extend;
},
addHeatingCoolingOutputClusterServer: () => m.deviceAddCustomCluster("heatingCoolingOutputClusterServer", {
name: "heatingCoolingOutputClusterServer",
ID: 0xff23,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
attributes: {
measuredTemperature: { name: "measuredTemperature", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff },
absMinHeatTemperatureLimit: { name: "absMinHeatTemperatureLimit", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff },
absMaxHeatTemperatureLimit: { name: "absMaxHeatTemperatureLimit", ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff },
absMinCoolTemperatureLimit: { name: "absMinCoolTemperatureLimit", ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff },
absMaxCoolTemperatureLimit: { name: "absMaxCoolTemperatureLimit", ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff },
minHeatTemperatureLimit: { name: "minHeatTemperatureLimit", ID: 0x0015, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
maxHeatTemperatureLimit: { name: "maxHeatTemperatureLimit", ID: 0x0016, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
minCoolTemperatureLimit: { name: "minCoolTemperatureLimit", ID: 0x0017, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
maxCoolTemperatureLimit: { name: "maxCoolTemperatureLimit", ID: 0x0018, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
heatTemperatureHighLimit: { name: "heatTemperatureHighLimit", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
heatTemperatureLowLimit: { name: "heatTemperatureLowLimit", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
coolTemperatureHighLimit: { name: "coolTemperatureHighLimit", ID: 0x0022, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
coolTemperatureLowLimit: { name: "coolTemperatureLowLimit", ID: 0x0023, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff },
coolingOutputMode: { name: "coolingOutputMode", ID: 0x0030, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true },
heatingOutputMode: { name: "heatingOutputMode", ID: 0x0031, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true },
maximumIdleTime: { name: "maximumIdleTime", ID: 0x0041, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 8784 },
antiIdleExerciseTime: { name: "antiIdleExerciseTime", ID: 0x0042, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 3600 },
preferredExerciseTime: { name: "preferredExerciseTime", ID: 0x0043, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 1439 },
minOffTime: { name: "minOffTime", ID: 0x0044, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true },
minOnTime: { name: "minOnTime", ID: 0x0045, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true },
maxOverallDutyCycle: { name: "maxOverallDutyCycle", ID: 0xe207, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, min: 900, max: 3600 },
overallDutyCyclePeriod: { name: "overallDutyCyclePeriod", ID: 0xe208, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 1440 },
clusterRevision: { name: "clusterRevision", ID: 0xfffd, type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xfffe },
},
commands: {},
commandsResponse: {},
}),
heatingOutputMode: (args) => m.enumLookup({
name: "heating_output_mode",
cluster: "heatingCoolingOutputClusterServer",
attribute: "heatingOutputMode",
description: "On devices with alternate heating output types, this selects which should be used to control the heating unit. This attribute is (mistakenly) also called pilot_mode on some devices.",
entityCategory: "config",
access: "ALL",
lookup: {
Disabled: 0,
Relay: 1,
OpenTherm: 2,
"Fil Pilote": 3,
"Relay NC": 4,
},
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
pilotMode: (args) => m.enumLookup({
name: "schneider_pilot_mode",
cluster: "heatingCoolingOutputClusterServer",
attribute: "heatingOutputMode",
description: "Controls piloting mode (from 'old description'). According to SE the attribute is called 'Heating output mode', and the corresponding custom cluster is heatingCoolingOutputClusterServer.",
entityCategory: "config",
access: "ALL",
lookup: {
contactor: 1,
pilot: 3,
},
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
addHvacUserInterfaceCfgCustomAttributes: () => m.deviceAddCustomCluster("hvacUserInterfaceCfg", {
name: "hvacUserInterfaceCfg",
ID: zigbee_herdsman_1.Zcl.Clusters.hvacUserInterfaceCfg.ID,
attributes: {
displayBrightnessActive: {
name: "displayBrightnessActive",
ID: 0xe000,
type: zigbee_herdsman_1.Zcl.DataType.UINT8,
write: true,
min: 0,
max: 100,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
displayBrightnessInactive: {
name: "displayBrightnessInactive",
ID: 0xe001,
type: zigbee_herdsman_1.Zcl.DataType.UINT8,
write: true,
min: 0,
max: 100,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
displayActiveTimeout: {
name: "displayActiveTimeout",
ID: 0xe002,
type: zigbee_herdsman_1.Zcl.DataType.UINT16,
write: true,
min: 5,
max: 600,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
},
commands: {},
commandsResponse: {},
}),
displayBrightnessActive: (args) => m.numeric({
name: "display_brightness_active",
cluster: "hvacUserInterfaceCfg",
attribute: "displayBrightnessActive",
description: "Sets brightness of the temperature display during active state",
entityCategory: "config",
unit: "%",
valueMin: 0,
valueMax: 100,
valueStep: 1,
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
displayBrightnessInactive: (args) => m.numeric({
name: "display_brightness_inactive",
cluster: "hvacUserInterfaceCfg",
attribute: "displayBrightnessInactive",
description: "Sets brightness of the temperature display during inactive state",
entityCategory: "config",
unit: "%",
valueMin: 0,
valueMax: 100,
valueStep: 1,
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
displayActiveTimeout: (args) => m.numeric({
name: "display_active_timeout",
cluster: "hvacUserInterfaceCfg",
attribute: "displayActiveTimeout",
description: "Sets timeout of the temperature display active state",
entityCategory: "config",
unit: "seconds",
valueMin: 5,
valueMax: 600,
valueStep: 5,
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
customTemperatureMeasurementCluster: () => m.deviceAddCustomCluster("msTemperatureMeasurement", {
name: "msTemperatureMeasurement",
ID: zigbee_herdsman_1.Zcl.Clusters.msTemperatureMeasurement.ID,
attributes: {
sensorCorrection: {
name: "sensorCorrection",
ID: 0xe020,
type: zigbee_herdsman_1.Zcl.DataType.INT16,
write: true,
min: -900,
max: 900,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
temperatureSensorType: {
name: "temperatureSensorType",
ID: 0xe021,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
},
commands: {},
commandsResponse: {},
}),
sensorCorrection: (args) => m.numeric({
name: "temperature_sensor_correction",
cluster: "msTemperatureMeasurement",
attribute: "sensorCorrection",
description: "This is a user correction, possibly negative, to be added to the temperature measured by the sensor.",
unit: "°C",
scale: 100,
valueMin: -9,
valueMax: 9,
valueStep: 0.01,
access: "ALL",
entityCategory: "config",
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
temperatureSensorType: (args) => m.enumLookup({
name: "temperature_sensor_type",
cluster: "msTemperatureMeasurement",
attribute: "temperatureSensorType",
description: "This is used to specify the type of temperature sensor connected to this input",
entityCategory: "config",
access: "ALL",
lookup: {
"2kΩ sensor from HRT/Alre": 1,
"10kΩ sensor from B+J": 2,
"12kΩ sensor from OJ": 3,
"15kΩ sensor from DEVI": 4,
"33kΩ sensor from EBERLE": 5,
"47kΩ sensor from CTM": 6,
"No sensor": 0xff,
},
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
customMeteringCluster: () => m.deviceAddCustomCluster("seMetering", {
name: "seMetering",
ID: zigbee_herdsman_1.Zcl.Clusters.seMetering.ID,
attributes: {
fixedLoadDemand: {
name: "fixedLoadDemand",
ID: 0x4510,
type: zigbee_herdsman_1.Zcl.DataType.UINT24,
write: true,
max: 0x7fffff,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
},
commands: {},
commandsResponse: {},
}),
fixedLoadDemand: (args) => m.numeric({
name: "fixed_load_demand",
cluster: "seMetering",
attribute: "fixedLoadDemand",
description: "This attribute specifies the demand of a switched load when it is energised",
entityCategory: "config",
unit: "W",
valueMin: 1,
valueMax: 3600,
valueStep: 1,
...args,
}),
customThermostatCluster: () => m.deviceAddCustomCluster("hvacThermostat", {
name: "hvacThermostat",
ID: zigbee_herdsman_1.Zcl.Clusters.hvacThermostat.ID,
attributes: {
schneiderWiserSpecific: {
name: "schneiderWiserSpecific",
ID: 0xe110,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
max: 0xff,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
controlStatus: {
name: "controlStatus",
ID: 0xe211,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
localTemperatureSourceSelect: {
name: "localTemperatureSourceSelect",
ID: 0xe212,
type: zigbee_herdsman_1.Zcl.DataType.UINT8,
write: true,
max: 0xfe,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
controlType: {
name: "controlType",
ID: 0xe213,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
thermostatApplication: {
name: "thermostatApplication",
ID: 0xe216,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
heatingFuel: {
name: "heatingFuel",
ID: 0xe217,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
heatTransferMedium: {
name: "heatTransferMedium",
ID: 0xe218,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
heatingEmitter: {
name: "heatingEmitter",
ID: 0xe21a,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
wiserSmartZoneMode: {
name: "wiserSmartZoneMode",
ID: 0xe010,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
wiserSmartHactConfig: {
name: "wiserSmartHactConfig",
ID: 0xe011,
type: zigbee_herdsman_1.Zcl.DataType.BITMAP8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
wiserSmartCurrentFilPiloteMode: {
name: "wiserSmartCurrentFilPiloteMode",
ID: 0xe020,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
write: true,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
wiserSmartValvePosition: {
name: "wiserSmartValvePosition",
ID: 0xe030,
type: zigbee_herdsman_1.Zcl.DataType.UINT8,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
wiserSmartValveCalibrationStatus: {
name: "wiserSmartValveCalibrationStatus",
ID: 0xe031,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
},
},
commands: {
schneiderWiserThermostatBoost: {
name: "schneiderWiserThermostatBoost",
ID: 0x80,
parameters: [
{ name: "command", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff },
{ name: "enable", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff },
{ name: "temperature", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
{ name: "duration", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
],
},
wiserSmartSetSetpoint: {
name: "wiserSmartSetSetpoint",
ID: 0xe0,
parameters: [
{ name: "operatingmode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
{ name: "zonemode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
{ name: "setpoint", type: zigbee_herdsman_1.Zcl.DataType.INT16, min: -32768, max: 32767 },
{ name: "reserved", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
],
},
wiserSmartSetFipMode: {
name: "wiserSmartSetFipMode",
ID: 0xe1,
parameters: [
{ name: "zonemode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
{ name: "fipmode", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff },
{ name: "reserved", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
],
},
wiserSmartCalibrateValve: { name: "wiserSmartCalibrateValve", ID: 0xe2, parameters: [] },
},
commandsResponse: {},
}),
controlStatus: (args) => m.enumLookup({
name: "control_status",
cluster: "hvacThermostat",
attribute: "controlStatus",
description: "This indicates the status of the thermostat and allows reporting of abnormal and fault conditions.",
entityCategory: "diagnostic",
access: "STATE",
lookup: {
"Normal Operation": 0x00,
"No Temperature": 0x20,
"Remote Demand Override": 0x40,
"Window Open": 0x41,
"Local Force On": 0x61,
Maintenance: 0x82,
"Output Temporal Limit": 0x83,
"Sensor Fault": 0x84,
},
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
...args,
}),
localTemperatureSourceSelect: () => m.enumLookup({
name: "local_temperature_source_select",
cluster: "hvacThermostat",
attribute: "localTemperatureSourceSelect",
description: "On devices with more than one temperature input, this selects which should be used for LocalTemperature.",
entityCategory: "config",
lookup: { Ambient: 2, External: 3 },
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
controlType: () => m.enumLookup({
name: "control_type",
cluster: "hvacThermostat",
attribute: "controlType",
description: "'On/Off', 'PI' and 'None' supported. This specifies the type of control algorithm to be used to regulate temperature.",
entityCategory: "config",
lookup: { "On/Off": 0, PI: 1, None: 0xff },
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
thermostatApplication: () => m.enumLookup({
name: "thermostat_application",
cluster: "hvacThermostat",
attribute: "thermostatApplication",
description: "This is used to specify what the Thermostat is regulating. 'Occupied Space' - heating where the room temperature is used as the control value, 'Floor' - Floor warming applications where the temperature of the floor itself is regulated.",
entityCategory: "config",
lookup: { "Occupied Space": 0, Floor: 1, "Not known": 0xff },
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
heatingFuel: () => m.enumLookup({
name: "heating_fuel",
cluster: "hvacThermostat",
attribute: "heatingFuel",
description: "Type of fuel used for heating.",
entityCategory: "config",
lookup: {
electricity: 0x00,
gas: 0x01,
oil: 0x02,
solid_fuel: 0x03,
solar: 0x04,
community_heating: 0x05,
heat_pump: 0x06,
not_specified: 0xff,
},
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
heatTransferMedium: () => m.enumLookup({
name: "heat_transfer_medium",
cluster: "hvacThermostat",
attribute: "heatTransferMedium",
description: "Medium used to transfer heat.",
entityCategory: "config",
lookup: { nothing: 0x00, hydronic: 0x01, air: 0x02 },
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
heatingEmitter: () => m.enumLookup({
name: "heating_emitter",
cluster: "hvacThermostat",
attribute: "heatingEmitter",
description: "This is used to specify the heat emitter.",
entityCategory: "config",
lookup: { None: 0, Radiator: 1, "Fan Assisted Radiator": 2, "Radiant Panel": 3, Floor: 4, "Not specified": 0xff },
zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC },
}),
addWiserDeviceInfoCluster: () => m.deviceAddCustomCluster("wiserDeviceInfo", {
name: "wiserDeviceInfo",
ID: 0xfe03,
attributes: {
deviceInfo: { name: "deviceInfo", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
},
commands: {},
commandsResponse: {},
}),
addSchneiderLightSwitchConfigurationCluster: () => m.deviceAddCustomCluster("manuSpecificSchneiderLightSwitchConfiguration", {
name: "manuSpecificSchneiderLightSwitchConfiguration",
ID: 0xff17,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
attributes: {
ledIndication: { name: "ledIndication", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
upSceneID: { name: "upSceneID", ID: 0x0010, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
upGroupID: { name: "upGroupID", ID: 0x0011, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff },
downSceneID: { name: "downSceneID", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
downGroupID: { name: "downGroupID", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff },
switchActions: { name: "switchActions", ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
},
commands: {},
commandsResponse: {},
}),
addSchneiderFanSwitchConfigurationCluster: () => m.deviceAddCustomCluster("manuSpecificSchneiderFanSwitchConfiguration", {
name: "manuSpecificSchneiderFanSwitchConfiguration",
ID: 0xfc04,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
attributes: {
ledIndication: { name: "ledIndication", ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
ledOrientation: { name: "ledOrientation", ID: 0x0060, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
},
commands: {},
commandsResponse: {},
}),
addSchneiderLightingBallastCfgCluster: () => m.deviceAddCustomCluster("lightingBallastCfg", {
name: "lightingBallastCfg",
ID: zigbee_herdsman_1.Zcl.Clusters.lightingBallastCfg.ID,
attributes: {
wiserControlMode: {
name: "wiserControlMode",
ID: 0xe000,
type: zigbee_herdsman_1.Zcl.DataType.ENUM8,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
write: true,
max: 0xff,
},
},
commands: {},
commandsResponse: {},
}),
};
const tzLocal = {
lift_duration: {
key: ["lift_duration"],
convertSet: async (entity, key, value, meta) => {
await entity.write(0x0102, { 57344: { value, type: 0x21 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
return { state: { lift_duration: value } };
},
},
fan_mode: {
...tz.fan_mode,
convertSet: async (entity, key, value, meta) => {
utils.assertString(value);
if (value.toLowerCase() === "on")
value = "low";
return await tz.fan_mode.convertSet(entity, key, value, meta);
},
},
wiser_dimmer_mode: {
key: ["dimmer_mode"],
convertSet: async (entity, key, value, meta) => {
await entity.write("lightingBallastCfg", { wiserControlMode: utils.getKey(constants.wiserDimmerControlMode, value, value, Number) }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
return { state: { dimmer_mode: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("lightingBallastCfg", ["wiserControlMode"], {
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC,
});
},
},
wiser_fip_setting: {
key: ["fip_setting"],
convertSet: async (entity, key, value, meta) => {
utils.assertString(value, key);
const zoneLookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
const zonemodeNum = utils.getFromLookup(meta.state.zone_mode, zoneLookup);
const fipLookup = { comfort: 0, "comfort_-1": 1, "comfort_-2": 2, energy_saving: 3, frost_protection: 4, off: 5 };
value = value.toLowerCase();
utils.validateValue(value, Object.keys(fipLookup));
const fipmodeNum = utils.getFromLookup(value, fipLookup);
const payload = {
zonemode: zonemodeNum,
fipmode: fipmodeNum,
reserved: 0xff,
};
await entity.command("hvacThermostat", "wiserSmartSetFipMode", payload, { srcEndpoint: 11, disableDefaultResponse: true });
return { state: { fip_setting: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("hvacThermostat", ["wiserSmartCurrentFilPiloteMode"]);
},
},
wiser_hact_config: {
key: ["hact_config"],
convertSet: async (entity, key, value, meta) => {
utils.assertString(value, key);
const lookup = { unconfigured: 0x00, setpoint_switch: 0x80, setpoint_fip: 0x82, fip_fip: 0x83 };
value = value.toLowerCase();
const mode = utils.getFromLookup(value, lookup);
await entity.write("hvacThermostat", { 57361: { value: mode, type: 0x18 } });
return { state: { hact_config: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("hvacThermostat", ["wiserSmartHactConfig"]);
},
},
wiser_zone_mode: {
key: ["zone_mode"],
convertSet: async (entity, key, value, meta) => {
const lookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
const zonemodeNum = utils.getFromLookup(value, lookup);
await entity.write("hvacThermostat", { 57360: { value: zonemodeNum, type: 0x30 } });
return { state: { zone_mode: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("hvacThermostat", ["wiserSmartZoneMode"]);
},
},
wiser_vact_calibrate_valve: {
key: ["calibrate_valve"],
convertSet: async (entity, key, value, meta) => {
await entity.command("hvacThermostat", "wiserSmartCalibrateValve", {}, { srcEndpoint: 11, disableDefaultResponse: true });
return { state: { calibrate_valve: value } };
},
},
};
const fzLocal = {
schneider_ui_action: {
cluster: "wiserDeviceInfo",
type: "attributeReport",
convert: (model, msg, publish, options, meta) => {
if (utils.hasAlreadyProcessedMessage(msg, model))
return;
const data = msg.data.deviceInfo.split(",");
if (data[0] === "UI" && data[1]) {
const result = { action: utils.toSnakeCase(data[1]) };
let screenAwake = globalStore.getValue(msg.endpoint, "screenAwake");
screenAwake = screenAwake !== undefined ? screenAwake : false;
const keypadLockedNumber = Number(msg.endpoint.getClusterAttributeValue("hvacUserInterfaceCfg", "keypadLockout"));
const keypadLocked = keypadLockedNumber !== undefined ? keypadLockedNumber !== 0 : false;
// Emulate UI temperature update
if (data[1] === "ScreenWake") {
globalStore.putValue(msg.endpoint, "screenAwake", true);
}
else if (data[1] === "ScreenSleep") {
globalStore.putValue(msg.endpoint, "screenAwake", false);
}
else if (screenAwake && !keypadLocked) {
let occupiedHeatingSetpoint = Number(msg.endpoint.getClusterAttributeValue("hvacThermostat", "occupiedHeatingSetpoint"));
occupiedHeatingSetpoint = occupiedHeatingSetpoint != null ? occupiedHeatingSetpoint : 400;
if (data[1] === "ButtonPressMinusDown") {
occupiedHeatingSetpoint -= 50;
}
else if (data[1] === "ButtonPressPlusDown") {
occupiedHeatingSetpoint += 50;
}
msg.endpoint.saveClusterAttributeKeyValue("hvacThermostat", { occupiedHeatingSetpoint: occupiedHeatingSetpoint });
result.occupied_heating_setpoint = occupiedHeatingSetpoint / 100;
}
return result;
}
},
},
schneider_powertag: {
cluster: "greenPower",
type: ["commandNotification", "commandCommissioningNotification"],
convert: async (model, msg, publish, options, meta) => {
if (msg.type !== "commandNotification") {
return;
}
const commandID = msg.data.commandID;
if (utils.hasAlreadyProcessedMessage(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
return;
const rxAfterTx = msg.data.options & (1 << 11);
const ret = {};
switch (commandID) {
case 0xa1: {
const attr = msg.data.commandFrame.attributes;
const clusterID = msg.data.commandFrame.clusterID;
switch (clusterID) {
case 2820: {
// haElectricalMeasurement
const acCurrentDivisor = attr.acCurrentDivisor;
const acVoltageDivisor = attr.acVoltageDivisor;
const acFrequencyDivisor = attr.acFrequencyDivisor;
const powerDivisor = attr.powerDivisor;
if (attr.rmsVoltage !== undefined) {
ret.voltage_phase_a = attr.rmsVoltage / acVoltageDivisor;
}
if (attr.rmsVoltagePhB !== undefined) {
ret.voltage_phase_b = attr.rmsVoltagePhB / acVoltageDivisor;
}
if (attr.rmsVoltagePhC !== undefined) {
ret.voltage_phase_c = attr.rmsVoltagePhC / acVoltageDivisor;
}
if (attr["19200"] !== undefined) {