homey-zigbeedriver
Version:
This module can be used to make the development of Zigbee apps for Homey easier.
92 lines (78 loc) • 3.1 kB
JavaScript
'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 { endpoint } = this._getClusterCapabilityConfiguration('windowcoverings_set', CLUSTER.WINDOW_COVERING);
const windowCoveringEndpoint = endpoint ?? 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, this.invertPercentageLiftValue ? 1 - value : 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, this.invertPercentageLiftValue ? 100 - value : 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;
},
};