zigbee-herdsman-converters
Version:
Collection of device converters to be used with zigbee-herdsman
871 lines • 41.5 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 exposes = __importStar(require("../lib/exposes"));
const m = __importStar(require("../lib/modernExtend"));
const reporting = __importStar(require("../lib/reporting"));
const tuya = __importStar(require("../lib/tuya"));
const utils = __importStar(require("../lib/utils"));
const e = exposes.presets;
const ea = exposes.access;
const NS = "zhc:sdevices";
const { tuyaMagicPacket, tuyaOnOffActionLegacy } = tuya.modernExtend;
const manufacturerOptions = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SBERDEVICES_LTD };
const defaultResponseOptions = { disableDefaultResponse: false };
const sdevices = {
fz: {
emergency_shutoff_state: {
cluster: "manuSpecificSDevices",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
if (msg.data.emergencyShutoffState !== undefined) {
const stateBitmap = msg.data.emergencyShutoffState;
const emergencyOvervoltage = stateBitmap & 0x01;
const emergencyUndervoltage = (stateBitmap & 0x02) >>> 1;
const emergencyOvercurrent = (stateBitmap & 0x04) >>> 2;
const emergencyOverheat = (stateBitmap & 0x08) >>> 3;
return {
emergency_overvoltage: !!emergencyOvervoltage,
emergency_undervoltage: !!emergencyUndervoltage,
emergency_overcurrent: !!emergencyOvercurrent,
emergency_overheat: !!emergencyOverheat,
};
}
},
},
led_indicator_settings: {
cluster: "manuSpecificSDevices",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
const result = {};
if (msg.data.ledIndicatorOnEnable !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_on_enable", msg, model, meta)] = msg.data.ledIndicatorOnEnable ? "ON" : "OFF";
}
if (msg.data.ledIndicatorOnH !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_on_h", msg, model, meta)] = msg.data.ledIndicatorOnH;
}
if (msg.data.ledIndicatorOnS !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_on_s", msg, model, meta)] = msg.data.ledIndicatorOnS;
}
if (msg.data.ledIndicatorOnB !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_on_b", msg, model, meta)] = msg.data.ledIndicatorOnB;
}
if (msg.data.ledIndicatorOffEnable !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_off_enable", msg, model, meta)] = msg.data.ledIndicatorOffEnable
? "ON"
: "OFF";
}
if (msg.data.ledIndicatorOffH !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_off_h", msg, model, meta)] = msg.data.ledIndicatorOffH;
}
if (msg.data.ledIndicatorOffS !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_off_s", msg, model, meta)] = msg.data.ledIndicatorOffS;
}
if (msg.data.ledIndicatorOffB !== undefined) {
result[utils.postfixWithEndpointName("led_indicator_off_b", msg, model, meta)] = msg.data.ledIndicatorOffB;
}
return result;
},
},
multistate_input: {
cluster: "genMultistateInput",
type: ["attributeReport"],
convert: (model, msg, publish, options, meta) => {
const actionLookup = { 0: "hold", 1: "single", 2: "double" };
const value = msg.data.presentValue;
const action = actionLookup[value];
return { action: utils.postfixWithEndpointName(action, msg, model, meta) };
},
},
decouple_relay: {
cluster: "genOnOff",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
const state = {};
if (msg.data.sdevicesRelayDecouple !== undefined) {
const relayDecoupleLookup = { 0: "control_relay", 1: "decoupled" };
state[utils.postfixWithEndpointName("relay_mode", msg, model, meta)] = utils.getFromLookup(msg.data.sdevicesRelayDecouple, relayDecoupleLookup);
}
return state;
},
},
allow_double_click: {
cluster: "manuSpecificSDevices",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
const result = {};
if (msg.data.buttonEnableMultiClick !== undefined) {
result[utils.postfixWithEndpointName("allow_double_click", msg, model, meta)] = msg.data.buttonEnableMultiClick ? "ON" : "OFF";
}
return result;
},
},
},
tz: {
custom_on_off: {
...tz.on_off,
key: ["state"],
},
led_indicator_on_settings: {
key: ["led_indicator_on_enable", "led_indicator_on_h", "led_indicator_on_s", "led_indicator_on_b"],
convertSet: async (entity, key, value, meta) => {
utils.assertString(key);
const payload = {};
switch (key) {
case "led_indicator_on_enable":
utils.assertString(value);
payload.ledIndicatorOnEnable = value.toUpperCase() === "ON" ? 1 : 0;
break;
case "led_indicator_on_h":
payload.ledIndicatorOnH = value;
break;
case "led_indicator_on_s":
payload.ledIndicatorOnS = value;
break;
case "led_indicator_on_b":
payload.ledIndicatorOnB = value;
break;
}
await m.determineEndpoint(entity, meta, "manuSpecificSDevices").write("manuSpecificSDevices", payload, defaultResponseOptions);
return { state: { [key]: value } };
},
convertGet: async (entity, key, meta) => {
await m
.determineEndpoint(entity, meta, "manuSpecificSDevices")
.read("manuSpecificSDevices", ["ledIndicatorOnEnable", "ledIndicatorOnH", "ledIndicatorOnS", "ledIndicatorOnB"], defaultResponseOptions);
},
},
led_indicator_off_settings: {
key: ["led_indicator_off_enable", "led_indicator_off_h", "led_indicator_off_s", "led_indicator_off_b"],
convertSet: async (entity, key, value, meta) => {
utils.assertString(key);
const payload = {};
switch (key) {
case "led_indicator_off_enable":
utils.assertString(value);
payload.ledIndicatorOffEnable = value.toUpperCase() === "ON" ? 1 : 0;
break;
case "led_indicator_off_h":
payload.ledIndicatorOffH = value;
break;
case "led_indicator_off_s":
payload.ledIndicatorOffS = value;
break;
case "led_indicator_off_b":
payload.ledIndicatorOffB = value;
break;
}
await m.determineEndpoint(entity, meta, "manuSpecificSDevices").write("manuSpecificSDevices", payload, defaultResponseOptions);
return { state: { [key]: value } };
},
convertGet: async (entity, key, meta) => {
await m
.determineEndpoint(entity, meta, "manuSpecificSDevices")
.read("manuSpecificSDevices", ["ledIndicatorOffEnable", "ledIndicatorOffH", "ledIndicatorOffS", "ledIndicatorOffB"], defaultResponseOptions);
},
},
identify: {
key: ["identify"],
options: tz.identify.options,
convertSet: async (entity, key, value, meta) => {
const identifyTimeout = meta.options.identify_timeout ?? 30;
await entity.command("genIdentify", "identify", { identifytime: identifyTimeout }, utils.getOptions(meta.mapped, entity));
},
},
decouple_relay: {
key: ["relay_mode"],
convertSet: async (entity, key, value, meta) => {
if (typeof value !== "string") {
return;
}
const relayDecoupleLookup = { control_relay: 0, decoupled: 1 };
if (relayDecoupleLookup[value] === undefined) {
throw new Error(`relay_mode was called with an invalid value (${value})`);
}
utils.assertEndpoint(entity);
await utils
.enforceEndpoint(entity, key, meta)
.write("genOnOff", { sdevicesRelayDecouple: relayDecoupleLookup[value] }, manufacturerOptions);
return { state: { relay_mode: value.toLowerCase() } };
},
convertGet: async (entity, key, meta) => {
utils.assertEndpoint(entity);
await utils.enforceEndpoint(entity, key, meta).read("genOnOff", ["sdevicesRelayDecouple"], manufacturerOptions);
},
},
allow_double_click: {
key: ["allow_double_click"],
convertSet: async (entity, key, value, meta) => {
if (typeof value !== "string") {
return;
}
const payload = {};
payload.buttonEnableMultiClick = value.toUpperCase() === "ON" ? 1 : 0;
await m.determineEndpoint(entity, meta, "manuSpecificSDevices").write("manuSpecificSDevices", payload, defaultResponseOptions);
return { state: { [key]: value } };
},
convertGet: async (entity, key, meta) => {
await m
.determineEndpoint(entity, meta, "manuSpecificSDevices")
.read("manuSpecificSDevices", ["buttonEnableMultiClick"], defaultResponseOptions);
},
},
},
};
const sdevicesCustomClusterDefinition = {
ID: 0xfccf,
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SBERDEVICES_LTD,
attributes: {
buttonEnableMultiClick: { ID: 0x1002, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
childLock: { ID: 0x1003, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
ledIndicatorOnEnable: { ID: 0x2001, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
ledIndicatorOnH: { ID: 0x2002, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
ledIndicatorOnS: { ID: 0x2003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
ledIndicatorOnB: { ID: 0x2004, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
ledIndicatorOffEnable: { ID: 0x2005, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
ledIndicatorOffH: { ID: 0x2006, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
ledIndicatorOffS: { ID: 0x2007, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
ledIndicatorOffB: { ID: 0x2008, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
emergencyShutoffState: { ID: 0x3001, type: zigbee_herdsman_1.Zcl.DataType.BITMAP16 },
emergencyShutoffRecovery: { ID: 0x3002, type: zigbee_herdsman_1.Zcl.DataType.BITMAP16 },
upperVoltageThreshold: { ID: 0x3011, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
lowerVoltageThreshold: { ID: 0x3012, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
upperCurrentThreshold: { ID: 0x3013, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
upperTempThreshold: { ID: 0x3014, type: zigbee_herdsman_1.Zcl.DataType.INT16 },
rmsVoltageMv: { ID: 0x4001, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
rmsCurrentMa: { ID: 0x4002, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
activePowerMw: { ID: 0x4003, type: zigbee_herdsman_1.Zcl.DataType.INT32 },
},
commands: {},
commandsResponse: {},
};
const sdevicesExtend = {
sdevicesCustomCluster: () => m.deviceAddCustomCluster("manuSpecificSDevices", sdevicesCustomClusterDefinition),
genOnOffCluster: () => m.deviceAddCustomCluster("genOnOff", {
ID: zigbee_herdsman_1.Zcl.Clusters.genOnOff.ID,
attributes: {
sdevicesRelayDecouple: { ID: 0x10dc, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SBERDEVICES_LTD },
},
commands: {},
commandsResponse: {},
}),
onOffRelayDecouple: (args) => m.enumLookup({
name: "relay_mode",
description: "Decoupled mode for button",
cluster: "genOnOff",
attribute: "sdevicesRelayDecouple",
lookup: { control_relay: 0, decoupled: 1 },
zigbeeCommandOptions: manufacturerOptions,
...args,
}),
ledIndicatorSettings: () => {
const fromZigbee = [
{
cluster: "manuSpecificSDevices",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
const result = {};
if (msg.data.ledIndicatorOnEnable !== undefined) {
result.led_indicator_on_enable = msg.data.ledIndicatorOnEnable ? "ON" : "OFF";
}
if (msg.data.ledIndicatorOnH !== undefined) {
result.led_indicator_on_h = msg.data.ledIndicatorOnH;
}
if (msg.data.ledIndicatorOnS !== undefined) {
result.led_indicator_on_s = msg.data.ledIndicatorOnS;
}
if (msg.data.ledIndicatorOnB !== undefined) {
result.led_indicator_on_b = msg.data.ledIndicatorOnB;
}
if (msg.data.ledIndicatorOffEnable !== undefined) {
result.led_indicator_off_enable = msg.data.ledIndicatorOffEnable ? "ON" : "OFF";
}
if (msg.data.ledIndicatorOffH !== undefined) {
result.led_indicator_off_h = msg.data.ledIndicatorOffH;
}
if (msg.data.ledIndicatorOffS !== undefined) {
result.led_indicator_off_s = msg.data.ledIndicatorOffS;
}
if (msg.data.ledIndicatorOffB !== undefined) {
result.led_indicator_off_b = msg.data.ledIndicatorOffB;
}
return result;
},
},
];
const toZigbee = [
{
key: ["led_indicator_on_enable", "led_indicator_on_h", "led_indicator_on_s", "led_indicator_on_b"],
convertSet: async (entity, key, value, meta) => {
const payload = {};
switch (key) {
case "led_indicator_on_enable":
utils.assertString(value);
payload.ledIndicatorOnEnable = value.toUpperCase() === "ON" ? 1 : 0;
break;
case "led_indicator_on_h":
payload.ledIndicatorOnH = value;
break;
case "led_indicator_on_s":
payload.ledIndicatorOnS = value;
break;
case "led_indicator_on_b":
payload.ledIndicatorOnB = value;
break;
}
await entity.write("manuSpecificSDevices", payload, defaultResponseOptions);
return { state: { [key]: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("manuSpecificSDevices", ["ledIndicatorOnEnable", "ledIndicatorOnH", "ledIndicatorOnS", "ledIndicatorOnB"], defaultResponseOptions);
},
},
{
key: ["led_indicator_off_enable", "led_indicator_off_h", "led_indicator_off_s", "led_indicator_off_b"],
convertSet: async (entity, key, value, meta) => {
const payload = {};
switch (key) {
case "led_indicator_off_enable":
utils.assertString(value);
payload.ledIndicatorOffEnable = value.toUpperCase() === "ON" ? 1 : 0;
break;
case "led_indicator_off_h":
payload.ledIndicatorOffH = value;
break;
case "led_indicator_off_s":
payload.ledIndicatorOffS = value;
break;
case "led_indicator_off_b":
payload.ledIndicatorOffB = value;
break;
}
await entity.write("manuSpecificSDevices", payload, defaultResponseOptions);
return { state: { [key]: value } };
},
convertGet: async (entity, key, meta) => {
await entity.read("manuSpecificSDevices", ["ledIndicatorOffEnable", "ledIndicatorOffH", "ledIndicatorOffS", "ledIndicatorOffB"], defaultResponseOptions);
},
},
];
const exposes = [
e
.binary("led_indicator_on_enable", ea.ALL, "ON", "OFF")
.withLabel("LED indication")
.withDescription("Is LED indicator enabled in ON state"),
e
.numeric("led_indicator_on_h", ea.ALL)
.withUnit("°")
.withValueMin(0)
.withValueMax(359)
.withLabel("Hue")
.withDescription("Hue of LED in ON state"),
e
.numeric("led_indicator_on_s", ea.ALL)
.withValueMin(0)
.withValueMax(0xfe)
.withLabel("Saturation")
.withDescription("Saturation of LED in ON state"),
e
.numeric("led_indicator_on_b", ea.ALL)
.withValueMin(1)
.withValueMax(0xfe)
.withLabel("Brightness")
.withDescription("Brightness of LED in ON state"),
e
.binary("led_indicator_off_enable", ea.ALL, "ON", "OFF")
.withLabel("LED indication")
.withDescription("Is LED indicator enabled in OFF state"),
e
.numeric("led_indicator_off_h", ea.ALL)
.withUnit("°")
.withValueMin(0)
.withValueMax(359)
.withLabel("Hue")
.withDescription("Hue of LED in OFF state"),
e
.numeric("led_indicator_off_s", ea.ALL)
.withValueMin(0)
.withValueMax(0xfe)
.withLabel("Saturation")
.withDescription("Saturation of LED in OFF state"),
e
.numeric("led_indicator_off_b", ea.ALL)
.withValueMin(1)
.withValueMax(0xfe)
.withLabel("Brightness")
.withDescription("Brightness of LED in OFF state"),
];
return { exposes, fromZigbee, toZigbee, isModernExtend: true };
},
electricityMeter: () => {
const exposes = [e.voltage().withAccess(ea.STATE_GET), e.current().withAccess(ea.STATE_GET), e.power().withAccess(ea.STATE_GET)];
const fromZigbee = [
{
cluster: "manuSpecificSDevices",
type: ["attributeReport", "readResponse"],
convert: (model, msg, publish, options, meta) => {
if (utils.hasAlreadyProcessedMessage(msg, model))
return;
const lookup = [
{ key: "rmsVoltageMv", name: "voltage", multiplier: 0.001 },
{ key: "rmsCurrentMa", name: "current", multiplier: 0.001 },
{ key: "activePowerMw", name: "power", multiplier: 0.001 },
];
const payload = {};
for (const entry of lookup) {
if (msg.data[entry.key] !== undefined) {
const value = msg.data[entry.key] * entry.multiplier;
payload[entry.name] = value;
}
}
return payload;
},
},
];
const toZigbee = [
{
key: ["voltage"],
convertGet: async (entity, key, meta) => {
await entity.read("manuSpecificSDevices", ["rmsVoltageMv"]);
},
},
{
key: ["current"],
convertGet: async (entity, key, meta) => {
await entity.read("manuSpecificSDevices", ["rmsCurrentMa"]);
},
},
{
key: ["power"],
convertGet: async (entity, key, meta) => {
await entity.read("manuSpecificSDevices", ["activePowerMw"]);
},
},
];
return { exposes, fromZigbee, toZigbee, isModernExtend: true };
},
childLock: () => m.binary({
name: "child_lock",
cluster: "manuSpecificSDevices",
attribute: "childLock",
description: "Enable child lock to prevent manual button operation",
valueOn: ["ON", 0x01],
valueOff: ["OFF", 0x00],
zigbeeCommandOptions: manufacturerOptions,
}),
deviceTemperature: () => m.numeric({
name: "device_temperature",
cluster: "genDeviceTempCfg",
attribute: "currentTemperature",
description: "Temperature of the device",
unit: "°C",
access: "STATE_GET",
entityCategory: "diagnostic",
}),
emergencyShutoffRecovery: () => m.enumLookup({
name: "emergency_shutoff_recovery",
cluster: "manuSpecificSDevices",
attribute: "emergencyShutoffRecovery",
description: "Condition of automatic recovery after emergency shutoff",
lookup: { disabled: 0, voltage_is_good: 1 },
zigbeeCommandOptions: manufacturerOptions,
}),
upperVoltageThreshold: () => m.numeric({
name: "upper_voltage_threshold",
cluster: "manuSpecificSDevices",
attribute: "upperVoltageThreshold",
description: "Upper voltage threshold",
valueMin: 230000,
valueMax: 260000,
valueStep: 1000,
unit: "mV",
zigbeeCommandOptions: manufacturerOptions,
}),
lowerVoltageThreshold: () => m.numeric({
name: "lower_voltage_threshold",
cluster: "manuSpecificSDevices",
attribute: "lowerVoltageThreshold",
description: "Lower voltage threshold (use with caution)",
valueMin: 100000,
valueMax: 230000,
valueStep: 1000,
unit: "mV",
zigbeeCommandOptions: manufacturerOptions,
}),
upperCurrentThreshold: () => m.numeric({
name: "upper_current_threshold",
cluster: "manuSpecificSDevices",
attribute: "upperCurrentThreshold",
description: "Upper current threshold",
valueMin: 100,
valueMax: 16000,
valueStep: 100,
unit: "mA",
zigbeeCommandOptions: manufacturerOptions,
}),
temperatureThreshold: () => m.numeric({
name: "temperature_threshold",
cluster: "manuSpecificSDevices",
attribute: "upperTempThreshold",
description: "Overtemperature threshold (use with caution)",
valueMin: -200,
valueMax: 200,
valueStep: 1,
unit: "°C",
zigbeeCommandOptions: manufacturerOptions,
}),
};
exports.definitions = [
{
fingerprint: tuya.fingerprint("SM0202", ["_TYZB01_2jzbhomb"]),
model: "SBDV-00029",
vendor: "Sber",
description: "Smart motion sensor",
extend: [
m.iasZoneAlarm({ zoneType: "occupancy", zoneAttributes: ["alarm_1", "tamper", "battery_low"], alarmTimeout: true }),
m.battery({ voltage: true, voltageReporting: true }),
],
},
{
fingerprint: tuya.fingerprint("TS0203", ["_TYZB01_epni2jgy"]),
model: "SBDV-00030",
vendor: "Sber",
description: "Smart opening sensor",
extend: [
m.ignoreClusterReport({ cluster: "genBasic" }),
m.iasZoneAlarm({ zoneType: "contact", zoneAttributes: ["alarm_1", "tamper", "battery_low"] }),
m.battery({ voltage: true, voltageReporting: true }),
],
},
{
fingerprint: tuya.fingerprint("TS0041A", ["_TYZB01_ub7urdza"]),
model: "SBDV-00032",
vendor: "Sber",
description: "Smart button",
extend: [
tuyaMagicPacket(),
tuyaOnOffActionLegacy({ actions: ["single", "double", "hold"] }),
m.battery({ percentageReporting: false }),
/*
* reporting.batteryPercentageRemaining removed as it was causing devices to fall of the network
* every 1 hour, with light flashing when it happened, extremely short battery life, 2 presses for
* action to register: https://github.com/Koenkk/zigbee2mqtt/issues/8072
* Initially wrapped in a try catch: https://github.com/Koenkk/zigbee2mqtt/issues/6313
*/
],
},
{
fingerprint: tuya.fingerprint("TS0201", ["_TZ3000_zfirri2d"]),
model: "SBDV-00079",
vendor: "Sber",
description: "Smart temperature and humidity sensor",
extend: [m.temperature(), m.humidity(), m.battery({ voltage: true, voltageReporting: true })],
},
{
fingerprint: tuya.fingerprint("TS0207", ["_TZ3000_c8bqthpo"]),
model: "SBDV-00154",
vendor: "Sber",
description: "Smart water leak sensor",
extend: [
m.ignoreClusterReport({ cluster: "genBasic" }),
m.iasZoneAlarm({ zoneType: "water_leak", zoneAttributes: ["alarm_1", "battery_low"] }),
m.battery(),
],
},
{
fingerprint: [{ modelID: "SBDV-00196", manufacturerName: "SDevices" }],
model: "SBDV-00196",
vendor: "Sber",
description: "Smart Wall Switch (with neutral, single button)",
fromZigbee: [fz.on_off, fz.power_on_behavior],
toZigbee: [sdevices.tz.custom_on_off, tz.power_on_behavior],
exposes: [e.switch(), e.power_on_behavior(["off", "on", "toggle", "previous"])],
extend: [
sdevicesExtend.sdevicesCustomCluster(),
sdevicesExtend.genOnOffCluster(),
m.binary({
name: "allow_double_click",
cluster: "manuSpecificSDevices",
attribute: "buttonEnableMultiClick",
description: "Allow detection of double clicks, may introduce delay in reaction when enabled",
valueOn: ["ON", 0x01],
valueOff: ["OFF", 0x00],
zigbeeCommandOptions: manufacturerOptions,
}),
sdevicesExtend.ledIndicatorSettings(),
m.identify(),
sdevicesExtend.onOffRelayDecouple({
name: "relay_mode",
description: "Decoupled mode for button",
}),
m.actionEnumLookup({
cluster: "genMultistateInput",
attribute: "presentValue",
actionLookup: { hold: 0, single: 1, double: 2 },
}),
],
ota: true,
configure: async (device, coordinatorEndpoint) => {
await device.getEndpoint(1).read("genOnOff", ["onOff", "startUpOnOff"]);
await device.getEndpoint(1).read("genBasic", ["serialNumber"]);
await device
.getEndpoint(1)
.read("manuSpecificSDevices", [
"ledIndicatorOnEnable",
"ledIndicatorOnH",
"ledIndicatorOnS",
"ledIndicatorOnB",
"ledIndicatorOffEnable",
"ledIndicatorOffH",
"ledIndicatorOffS",
"ledIndicatorOffB",
]);
await device.getEndpoint(1).read("manuSpecificSDevices", ["buttonEnableMultiClick"]);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["genOnOff", "genMultistateInput"]);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["haDiagnostic"]);
},
},
{
fingerprint: [{ modelID: "SBDV-00199", manufacturerName: "SDevices" }],
model: "SBDV-00199",
vendor: "Sber",
description: "Smart Wall Switch (with neutral, two buttons)",
fromZigbee: [
fz.on_off,
fz.power_on_behavior,
sdevices.fz.multistate_input,
sdevices.fz.led_indicator_settings,
sdevices.fz.decouple_relay,
sdevices.fz.allow_double_click,
],
toZigbee: [
sdevices.tz.custom_on_off,
tz.power_on_behavior,
sdevices.tz.identify,
sdevices.tz.led_indicator_on_settings,
sdevices.tz.led_indicator_off_settings,
sdevices.tz.decouple_relay,
sdevices.tz.allow_double_click,
],
exposes: (device, options) => {
const switchExposes = [];
const endpointsCount = 2;
switchExposes.push(e.action(["hold_switch_1", "hold_switch_2", "single_switch_1", "single_switch_2", "double_switch_1", "double_switch_2"]));
for (let i = 1; i <= endpointsCount; i++) {
const epName = `switch_${i}`;
const epPrefix = `(${i}) `;
switchExposes.push(e.switch().withEndpoint(epName));
switchExposes.push(e.power_on_behavior(["off", "on", "toggle", "previous"]).withLabel(`${epPrefix}Power-on behavior`).withEndpoint(epName));
switchExposes.push(e
.enum("relay_mode", ea.ALL, ["control_relay", "decoupled"])
.withLabel(`${epPrefix}Relay mode`)
.withDescription("Decoupled mode")
.withEndpoint(epName));
switchExposes.push(e
.binary("allow_double_click", ea.ALL, "ON", "OFF")
.withLabel(`${epPrefix}Allow double clicks`)
.withDescription("Allow detection of double clicks, may introduce delay in reaction when enabled")
.withEndpoint(epName));
switchExposes.push(e
.enum("identify", ea.SET, ["identify"])
.withLabel(`${epPrefix}Identify`)
.withDescription("Initiate device identification")
.withCategory("config")
.withEndpoint(epName));
switchExposes.push(e
.binary("led_indicator_on_enable", ea.ALL, "ON", "OFF")
.withLabel(`${epPrefix}LED indication`)
.withDescription("Is LED indicator enabled in ON state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_on_h", ea.ALL)
.withUnit("°")
.withValueMin(0)
.withValueMax(359)
.withLabel(`${epPrefix}Hue`)
.withDescription("Hue of LED in ON state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_on_s", ea.ALL)
.withValueMin(0)
.withValueMax(0xfe)
.withLabel(`${epPrefix}Saturation`)
.withDescription("Saturation of LED in ON state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_on_b", ea.ALL)
.withValueMin(1)
.withValueMax(0xfe)
.withLabel(`${epPrefix}Brightness`)
.withDescription("Brightness of LED in ON state")
.withEndpoint(epName));
switchExposes.push(e
.binary("led_indicator_off_enable", ea.ALL, "ON", "OFF")
.withLabel(`${epPrefix}LED indication`)
.withDescription("Is LED indicator enabled in OFF state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_off_h", ea.ALL)
.withUnit("°")
.withValueMin(0)
.withValueMax(359)
.withLabel(`${epPrefix}Hue`)
.withDescription("Hue of LED in OFF state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_off_s", ea.ALL)
.withValueMin(0)
.withValueMax(0xfe)
.withLabel(`${epPrefix}Saturation`)
.withDescription("Saturation of LED in OFF state")
.withEndpoint(epName));
switchExposes.push(e
.numeric("led_indicator_off_b", ea.ALL)
.withValueMin(1)
.withValueMax(0xfe)
.withLabel(`${epPrefix}Brightness`)
.withDescription("Brightness of LED in OFF state")
.withEndpoint(epName));
}
return [...switchExposes];
},
extend: [
sdevicesExtend.sdevicesCustomCluster(),
sdevicesExtend.genOnOffCluster(),
m.deviceEndpoints({ endpoints: { switch_1: 1, switch_2: 2 } }),
],
ota: true,
configure: async (device, coordinatorEndpoint) => {
if (!device.customClusters.manuSpecificSDevices) {
device.addCustomCluster("manuSpecificSDevices", sdevicesCustomClusterDefinition);
}
await device.getEndpoint(1).read("genBasic", ["serialNumber"]);
await device.getEndpoint(1).read("genOnOff", ["onOff", "startUpOnOff"]);
await device.getEndpoint(2).read("genOnOff", ["onOff", "startUpOnOff"]);
await device.getEndpoint(1).read("genOnOff", ["sdevicesRelayDecouple"], manufacturerOptions);
await device.getEndpoint(2).read("genOnOff", ["sdevicesRelayDecouple"], manufacturerOptions);
await device
.getEndpoint(1)
.read("manuSpecificSDevices", [
"buttonEnableMultiClick",
"ledIndicatorOnEnable",
"ledIndicatorOnH",
"ledIndicatorOnS",
"ledIndicatorOnB",
"ledIndicatorOffEnable",
"ledIndicatorOffH",
"ledIndicatorOffS",
"ledIndicatorOffB",
], manufacturerOptions);
await device
.getEndpoint(2)
.read("manuSpecificSDevices", [
"buttonEnableMultiClick",
"ledIndicatorOnEnable",
"ledIndicatorOnH",
"ledIndicatorOnS",
"ledIndicatorOnB",
"ledIndicatorOffEnable",
"ledIndicatorOffH",
"ledIndicatorOffS",
"ledIndicatorOffB",
], manufacturerOptions);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["genOnOff", "genMultistateInput"]);
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ["genOnOff", "genMultistateInput"]);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["manuSpecificSDevices"]);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["haDiagnostic"]);
device.save();
},
},
{
fingerprint: [{ modelID: "SBDV-00202", manufacturerName: "SDevices" }],
model: "SBDV-00202",
vendor: "Sber",
description: "Smart Wall Socket",
toZigbee: [sdevices.tz.custom_on_off, tz.power_on_behavior],
fromZigbee: [fz.on_off, fz.power_on_behavior, sdevices.fz.emergency_shutoff_state],
exposes: [
e.switch(),
e.power_on_behavior(["off", "on", "toggle", "previous"]),
e.binary("emergency_overvoltage", ea.STATE, true, false).withDescription("Overvoltage alarm is triggered").withCategory("diagnostic"),
e.binary("emergency_undervoltage", ea.STATE, true, false).withDescription("Undervoltage alarm is triggered").withCategory("diagnostic"),
e.binary("emergency_overcurrent", ea.STATE, true, false).withDescription("Overcurrent alarm is triggered").withCategory("diagnostic"),
e.binary("emergency_overheat", ea.STATE, true, false).withDescription("Overheat alarm is triggered").withCategory("diagnostic"),
],
extend: [
sdevicesExtend.sdevicesCustomCluster(),
m.identify(),
sdevicesExtend.deviceTemperature(),
sdevicesExtend.childLock(),
sdevicesExtend.electricityMeter(),
sdevicesExtend.ledIndicatorSettings(),
sdevicesExtend.emergencyShutoffRecovery(),
sdevicesExtend.upperVoltageThreshold(),
sdevicesExtend.lowerVoltageThreshold(),
sdevicesExtend.upperCurrentThreshold(),
sdevicesExtend.temperatureThreshold(),
],
ota: true,
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);
await endpoint.read("genBasic", ["serialNumber"]);
await endpoint.read("genOnOff", ["onOff", "startUpOnOff"]);
await endpoint.read("manuSpecificSDevices", ["childLock", "rmsVoltageMv", "rmsCurrentMa", "activePowerMw"]);
await endpoint.read("manuSpecificSDevices", [
"ledIndicatorOnEnable",
"ledIndicatorOnH",
"ledIndicatorOnS",
"ledIndicatorOnB",
"ledIndicatorOffEnable",
"ledIndicatorOffH",
"ledIndicatorOffS",
"ledIndicatorOffB",
]);
await endpoint.read("manuSpecificSDevices", [
"upperVoltageThreshold",
"lowerVoltageThreshold",
"upperCurrentThreshold",
"upperTempThreshold",
]);
await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genDeviceTempCfg", "manuSpecificSDevices"]);
await reporting.bind(endpoint, coordinatorEndpoint, ["haDiagnostic"]);
},
},
];
//# sourceMappingURL=sber.js.map