/
windowCovering.js
85 lines (73 loc) · 2.78 KB
/
windowCovering.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'use strict';
const { CLUSTER } = require('zigbee-clusters');
const { mapValueRange } = require('../../../util');
const UP_OPEN = 'upOpen';
const DOWN_CLOSE = 'downClose';
const REPORT_DEBOUNCER = 5000;
/**
* Cluster capability configuration for `windowcoverings_set`.
* @type {ClusterCapabilityConfiguration}
*/
module.exports = {
getOpts: {
getOnStart: true,
},
get: 'currentPositionLiftPercentage',
set: 'goToLiftPercentage',
/**
* @param {number} value
* @returns {Promise<null|{percentageLiftValue: number}>}
*/
async setParser(value) {
// Refresh timer or set new timer to prevent reports from updating the dim slider directly
// when set command from Homey
if (this._reportPercentageDebounce) {
this._reportPercentageDebounce.refresh();
} else {
this._reportPercentageDebounce = this.homey.setTimeout(() => {
this._reportDebounceEnabled = false;
this._reportPercentageDebounce = null;
}, REPORT_DEBOUNCER);
}
// Used to check if reports are generated based on set command from Homey
this._reportDebounceEnabled = true;
// Override goToLiftPercentage to enforce blind to open/close completely
if (value === 0 || value === 1) {
this.debug(`set → \`windowcoverings_set\`: ${value} → setParser → ${value === 1 ? UP_OPEN : DOWN_CLOSE}`);
const windowCoveringEndpoint = this.getClusterEndpoint(CLUSTER.WINDOW_COVERING);
if (windowCoveringEndpoint === null) throw new Error('missing_window_covering_cluster');
const windowCoveringCommand = value === 1 ? UP_OPEN : DOWN_CLOSE;
await this.zclNode.endpoints[windowCoveringEndpoint].clusters
.windowCovering[windowCoveringCommand]();
await this.setCapabilityValue('windowcoverings_set', value);
return null;
}
const mappedValue = mapValueRange(0, 1, 0, 100, value);
const gotToLiftPercentageCommand = {
// Round, otherwise might not be accepted by device
percentageLiftValue: Math.round(mappedValue),
};
this.debug(`set → \`windowcoverings_set\`: ${value} → setParser → goToLiftPercentage`, gotToLiftPercentageCommand);
// Send goToLiftPercentage command
return gotToLiftPercentageCommand;
},
report: 'currentPositionLiftPercentage',
/**
* @param {number} value
* @returns {null|number}
*/
reportParser(value) {
// Validate input
if (value < 0 || value > 100) return null;
// Parse input value
const parsedValue = mapValueRange(0, 100, 0, 1, value);
// Refresh timer if needed
if (this._reportPercentageDebounce) {
this._reportPercentageDebounce.refresh();
}
// If reports are not generated by set command from Homey update directly
if (!this._reportDebounceEnabled) return parsedValue;
// Return value
return null;
},
};