66 text,
77 binary,
88 windowCovering,
9- deviceAddCustomCluster,
109} = require("zigbee-herdsman-converters/lib/modernExtend");
1110const {assertString} = require("zigbee-herdsman-converters/lib/utils");
1211const reporting = require("zigbee-herdsman-converters/lib/reporting");
@@ -271,8 +270,8 @@ const romasku = {
271270 name,
272271 endpointName,
273272 lookup: { toggle: 0, momentary: 1 },
274- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
275- attribute: "switchType" ,
273+ cluster: 0xFC01 ,
274+ attribute: {ID: 0x0000, type: Zcl.DataType.ENUM8} ,
276275 description: "Type of cover switch: toggle (rocker) or momentary (push button)",
277276 entityCategory: "config",
278277 }),
@@ -284,8 +283,8 @@ const romasku = {
284283 ['detached', 0],
285284 ...Array.from({ length: output_cnt || 2 }, (_, i) => [`cover_${i + 1}`, i + 1])
286285 ]),
287- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
288- attribute: "coverIndex" ,
286+ cluster: 0xFC01 ,
287+ attribute: {ID: 0x0001, type: Zcl.DataType.UINT8} ,
289288 description: "Which cover to control locally (detached = no local control)",
290289 entityCategory: "config",
291290 }),
@@ -295,8 +294,8 @@ const romasku = {
295294 endpointName,
296295 valueOn: ["ON", 1],
297296 valueOff: ["OFF", 0],
298- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
299- attribute: "reversal" ,
297+ cluster: 0xFC01 ,
298+ attribute: {ID: 0x0002, type: Zcl.DataType.BOOLEAN} ,
300299 description: "Inverts UP/DOWN direction for inputs",
301300 access: "ALL",
302301 entityCategory: "config",
@@ -306,8 +305,8 @@ const romasku = {
306305 name,
307306 endpointName,
308307 lookup: { immediate: 0, short_press: 1, long_press: 2, hybrid: 3 },
309- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
310- attribute: "localMode" ,
308+ cluster: 0xFC01 ,
309+ attribute: {ID: 0x0003, type: Zcl.DataType.ENUM8} ,
311310 description: "When to trigger local cover: immediate (start/stop on press), short_press (trigger on release), long_press (trigger after long press duration), hybrid (trigger on release or continuous movement while held). Only affects momentary switches",
312311 entityCategory: "config",
313312 }),
@@ -316,17 +315,17 @@ const romasku = {
316315 name,
317316 endpointName,
318317 lookup: { immediate: 0, short_press: 1, long_press: 2, hybrid: 3 },
319- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
320- attribute: "bindedMode" ,
318+ cluster: 0xFC01 ,
319+ attribute: {ID: 0x0004, type: Zcl.DataType.ENUM8} ,
321320 description: "When to send commands to bound devices: immediate (start/stop on press), short_press (trigger on release), long_press (trigger after long press duration), hybrid (trigger on release or continuous movement while held). Only affects momentary switches",
322321 entityCategory: "config",
323322 }),
324323 coverSwitchLongPressDuration: (name, endpointName) =>
325324 numeric({
326325 name,
327326 endpointNames: [endpointName],
328- cluster: "manuSpecificTuyaCoverSwitchConfig" ,
329- attribute: "longPressDuration" ,
327+ cluster: 0xFC01 ,
328+ attribute: {ID: 0x0005, type: Zcl.DataType.UINT16} ,
330329 description: "Threshold in milliseconds to distinguish short press from long press",
331330 valueMin: 0,
332331 valueMax: 5000,
@@ -343,7 +342,7 @@ const romasku = {
343342 closing: 2
344343 },
345344 cluster: "closuresWindowCovering",
346- attribute: "moving" ,
345+ attribute: {ID: 0xff00, type: Zcl.DataType.ENUM8} ,
347346 description: "Cover movement status",
348347 entityCategory: "diagnostic",
349348 }),
@@ -354,7 +353,7 @@ const romasku = {
354353 valueOn: [true, 1],
355354 valueOff: [false, 0],
356355 cluster: "closuresWindowCovering",
357- attribute: "motorReversal" ,
356+ attribute: {ID: 0xff01, type: Zcl.DataType.BOOLEAN} ,
358357 description: "Reverse motor direction (swap OPEN/CLOSE relays)",
359358 entityCategory: "config",
360359 }),
@@ -363,7 +362,7 @@ const romasku = {
363362 name,
364363 endpointNames: [endpointName],
365364 cluster: "closuresWindowCovering",
366- attribute: "openTime" ,
365+ attribute: {ID: 0xff02, type: Zcl.DataType.UINT16} ,
367366 description: "Travel time for the OPENING direction (0.1 s precision). " +
368367 "For symmetric covers you only need to set this value. " +
369368 "close_time will fall back to open_time automatically.",
@@ -379,7 +378,7 @@ const romasku = {
379378 name,
380379 endpointNames: [endpointName],
381380 cluster: "closuresWindowCovering",
382- attribute: "closeTime" ,
381+ attribute: {ID: 0xff03, type: Zcl.DataType.UINT16} ,
383382 description: "Travel time for the CLOSING direction (0.1 s precision). " +
384383 "Set to 0 to use the same value as open_time. " +
385384 "Set explicitly only if closing speed differs from opening speed.",
@@ -395,7 +394,7 @@ const romasku = {
395394 name,
396395 endpointNames: [endpointName],
397396 cluster: "closuresWindowCovering",
398- attribute: "closedDeadzone" ,
397+ attribute: {ID: 0xff04, type: Zcl.DataType.UINT16} ,
399398 description: "Mechanical deadzone at the CLOSED end (0%) as a percentage of " +
400399 "total travel. Motor movement within this zone does not change the " +
401400 "reported position.",
@@ -409,7 +408,7 @@ const romasku = {
409408 name,
410409 endpointNames: [endpointName],
411410 cluster: "closuresWindowCovering",
412- attribute: "openDeadzone" ,
411+ attribute: {ID: 0xff05, type: Zcl.DataType.UINT16} ,
413412 description: "Mechanical deadzone at the OPEN end (100%) as a percentage of " +
414413 "total travel. Motor movement within this zone does not change the " +
415414 "reported position.",
@@ -436,35 +435,6 @@ const definitions = [
436435 {% if device .has_battery_cluster %}
437436 romasku.batteryPercentage(),
438437 {% endif %}
439- {% if device .coverSwitchNames %}
440- deviceAddCustomCluster("manuSpecificTuyaCoverSwitchConfig", {
441- ID: 0xFC01,
442- manufacturerCode: 0x125D,
443- attributes: {
444- switchType: {ID: 0x0000, type: Zcl.DataType.ENUM8, write: true},
445- coverIndex: {ID: 0x0001, type: Zcl.DataType.UINT8, write: true},
446- reversal: {ID: 0x0002, type: Zcl.DataType.BOOLEAN, write: true},
447- localMode: {ID: 0x0003, type: Zcl.DataType.ENUM8, write: true},
448- bindedMode: {ID: 0x0004, type: Zcl.DataType.ENUM8, write: true},
449- longPressDuration: {ID: 0x0005, type: Zcl.DataType.UINT16, write: true},
450- },
451- commands: {},
452- commandsResponse: {},
453- }),
454- {% endif %}
455- {% if device .coverNames %}
456- deviceAddCustomCluster("closuresWindowCovering", {
457- ID: 0x0102,
458- attributes: {
459- moving: {ID: 0xff00, type: Zcl.DataType.ENUM8},
460- motorReversal: {ID: 0xff01, type: Zcl.DataType.BOOLEAN, write: true},
461- openTime: {ID: 0xff02, type: Zcl.DataType.UINT16, write: true},
462- closeTime: {ID: 0xff03, type: Zcl.DataType.UINT16, write: true},
463- closedDeadzone: {ID: 0xff04, type: Zcl.DataType.UINT16, write: true},
464- openDeadzone: {ID: 0xff05, type: Zcl.DataType.UINT16, write: true},
465- },
466- }),
467- {% endif %}
468438 deviceEndpoints({ endpoints: {
469439 {% - for switchName in device .switchNames -%}
470440 "{{switchName}}": {{loop.index}},{{" "}}
@@ -597,7 +567,7 @@ const definitions = [
597567 await reporting.bind(cover{{loop.index}}, coordinatorEndpoint, ["closuresWindowCovering"]);
598568 await cover{{loop.index}}.configureReporting("closuresWindowCovering", [
599569 {
600- attribute: "moving" ,
570+ attribute: {ID: 0xff00, type: Zcl.DataType.ENUM8} ,
601571 minimumReportInterval: 0,
602572 maximumReportInterval: constants.repInterval.MAX,
603573 reportableChange: 1,
0 commit comments