homebridge-openhab2-complete
homebridge-openhab2-complete copied to clipboard
Heater/Cooler Accessory with sepparate min-max temp for thresholds
Homekit uses heatingThresholdTempItem and coolingThresholdTempItem to set the temperature when both heatingItem and coolingItem are sellected. I wasn't able to manipulate the currentTempItem throug homekit/Siri. I also needed to be able to set heating and cooling individualy so I played aroundwith the climate.js file.
I added seperate variables ( minHeatThrTemp, minCoolThrTemp etc) and edited the addHeatingThresholdCharacteristic and addCoolingThresholdCharacteristic functions..
Not sure if this could be implimented in some future release.
I have attached the edited file below.
Thanks for all the great work you are doing!
'use strict';
const {addNumericSensorCharacteristic,
addNumericSensorCharacteristicWithTransformation,
addNumericSensorActorCharacteristic,
addNumericSensorActorCharacteristicWithDistinctTransformation
} = require('./Numeric');
const CLIMATE_CONFIG = {
waterLevelItem: "waterLevelItem",
rotationSpeedItem: "rotationSpeedItem",
currentHumidityItem: "currentHumidityItem",
targetHumidityItem: "targetHumidityItem",
currentTempItem: "currentTempItem",
targetTempItem: "targetTempItem",
heatingThresholdTempItem: "heatingThresholdTempItem",
coolingThresholdTempItem: "coolingThresholdTempItem",
dehumidifierThresholdItem: "dehumidifierThresholdItem",
humidifierThresholdItem: "humidifierThresholdItem",
tempUnit: "tempUnit", // 'Celsius' (default), 'Fahrenheit'
minTemp: "minTemp",
maxTemp: "maxTemp",
minTempStep: "minTempStep",
//edit
minHeatThrTemp: "minHeatThrTemp",
maxHeatThrTemp: "maxHeatThrTemp",
minHeatThrTempStep: "minHeatThrTempStep",
minCoolThrTemp: "minCoolThrTemp",
maxCoolThrTemp: "maxCoolThrTemp",
minCoolThrTempStep: "minCoolThrTempStep",
//edit
minFanSpeed: "minFanSpeed",
maxFanSpeed: "maxFanSpeed",
minFanStep: "minFanStep"
};
const DEFAULT_MIN_TEMP = -100;
const DEFAULT_MAX_TEMP = 200;
const DEFAULT_MIN_TEMP_STEP = 0.1;
const DEFAULT_MIN_FAN_SPEED = 0;
const DEFAULT_MAX_FAN_SPEED = 100;
const DEFAULT_MIN_FAN_STEP = 1;
function addWaterLevelCharacteristic(service, optional) {
addNumericSensorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.WaterLevel), {item: CLIMATE_CONFIG.waterLevelItem}, optional);
}
function addRotationSpeedCharacteristic(service, optional) {
let thisMinSpeed = this._config[CLIMATE_CONFIG.minFanSpeed] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minFanSpeed]) : DEFAULT_MIN_FAN_SPEED;
let thisMaxSpeed = this._config[CLIMATE_CONFIG.maxFanSpeed] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.maxFanSpeed]) : DEFAULT_MAX_FAN_SPEED;
let thisMinStep = this._config[CLIMATE_CONFIG.minFanStep] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minFanStep]) : DEFAULT_MIN_FAN_STEP;
let rotationSpeedCharacteristic = service.getCharacteristic(this.Characteristic.RotationSpeed);
rotationSpeedCharacteristic.setProps({
minValue: thisMinSpeed,
maxValue: thisMaxSpeed,
minTempStep: thisMinStep
});
this._log.debug(`Applied minValue ${thisMinSpeed}, maxValue ${thisMaxSpeed} and minStep ${thisMinStep} for fan speed`);
addNumericSensorActorCharacteristic.bind(this)(service, rotationSpeedCharacteristic, {item: CLIMATE_CONFIG.rotationSpeedItem}, optional);
}
function addCurrentRelativeHumidityCharacteristic(service, optional) {
addNumericSensorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.CurrentRelativeHumidity), {item: CLIMATE_CONFIG.currentHumidityItem}, optional);
}
function addTargetRelativeHumidityCharacteristic(service, optional) {
addNumericSensorActorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.TargetRelativeHumidity), {item: CLIMATE_CONFIG.targetHumidityItem}, optional);
}
function addCurrentTemperatureCharacteristic(service, optional) {
let thisMinTemp = this._config[CLIMATE_CONFIG.minTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minTemp]) : DEFAULT_MIN_TEMP;
let thisMaxTemp = this._config[CLIMATE_CONFIG.maxTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.maxTemp]) : DEFAULT_MAX_TEMP;
let thisMinStep = this._config[CLIMATE_CONFIG.minTempStep] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minTempStep]) : DEFAULT_MIN_TEMP_STEP;
let transformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertFahrenheitToCelsius : parseFloat;
let currentTemperatureCharacteristic = service.getCharacteristic(this.Characteristic.CurrentTemperature);
currentTemperatureCharacteristic.setProps({
minValue: thisMinTemp,
maxValue: thisMaxTemp,
minStep: thisMinStep
});
this._log.debug(`Applied minValue ${thisMinTemp}, maxValue ${thisMaxTemp} and minStep ${thisMinStep} for temp`);
addNumericSensorCharacteristicWithTransformation.bind(this)(service,
currentTemperatureCharacteristic,
{item: CLIMATE_CONFIG.currentTempItem},
transformation,
optional
);
}
function addTargetTemperatureCharacteristic(service, optional) {
let thisMinTemp = this._config[CLIMATE_CONFIG.minTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minTemp]) : DEFAULT_MIN_TEMP;
let thisMaxTemp = this._config[CLIMATE_CONFIG.maxTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.maxTemp]) : DEFAULT_MAX_TEMP;
let thisMinStep = this._config[CLIMATE_CONFIG.minTempStep] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minTempStep]) : DEFAULT_MIN_TEMP_STEP;
let getTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertFahrenheitToCelsius : parseFloat;
let setTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertCelsiusToFahrenheit : parseFloat;
let targetTemperatureCharacteristic = service.getCharacteristic(this.Characteristic.TargetTemperature);
targetTemperatureCharacteristic.setProps({
minValue: thisMinTemp,
maxValue: thisMaxTemp,
minStep: thisMinStep
});
addNumericSensorActorCharacteristicWithDistinctTransformation.bind(this)(service,
targetTemperatureCharacteristic,
{item: CLIMATE_CONFIG.targetTempItem},
setTransformation,
getTransformation,
optional
);
}
function _convertFahrenheitToCelsius(val) {
return (((parseFloat(val)-32)*5)/9);
}
function _convertCelsiusToFahrenheit(val) {
return (((parseFloat(val) * 9)/5) + 32);
}
//edit
function addCoolingThresholdCharacteristic(service, optional) {
let thisMinTemp = this._config[CLIMATE_CONFIG.minCoolThrTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minCoolThrTemp]) : DEFAULT_MIN_TEMP;
let thisMaxTemp = this._config[CLIMATE_CONFIG.maxCoolThrTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.maxCoolThrTemp]) : DEFAULT_MAX_TEMP;
let thisMinStep = this._config[CLIMATE_CONFIG.minCoolThrTempStep] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minCoolThrTempStep]) : DEFAULT_MIN_TEMP_STEP;
let getTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertFahrenheitToCelsius : parseFloat;
let setTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertCelsiusToFahrenheit : parseFloat;
let CoolingThresholdCharacteristic = service.getCharacteristic(this.Characteristic.CoolingThresholdTemperature);
CoolingThresholdCharacteristic.setProps({
minValue: thisMinTemp,
maxValue: thisMaxTemp,
minStep: thisMinStep
});
addNumericSensorActorCharacteristicWithDistinctTransformation.bind(this)(service,
CoolingThresholdCharacteristic,
{item: CLIMATE_CONFIG.coolingThresholdTempItem},
setTransformation,
getTransformation,
optional
);
}
function addHeatingThresholdCharacteristic(service, optional) {
addNumericSensorActorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.HeatingThresholdTemperature), {item: CLIMATE_CONFIG.heatingThresholdTempItem}, optional);
}
function addHeatingThresholdCharacteristic(service, optional) {
let thisMinTemp = this._config[CLIMATE_CONFIG.minHeatThrTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minHeatThrTemp]) : DEFAULT_MIN_TEMP;
let thisMaxTemp = this._config[CLIMATE_CONFIG.maxHeatThrTemp] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.maxHeatThrTemp]) : DEFAULT_MAX_TEMP;
let thisMinStep = this._config[CLIMATE_CONFIG.minHeatThrTempStep] !== undefined ? parseFloat(this._config[CLIMATE_CONFIG.minHeatThrTempStep]) : DEFAULT_MIN_TEMP_STEP;
let getTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertFahrenheitToCelsius : parseFloat;
let setTransformation = this._config[CLIMATE_CONFIG.tempUnit] === "Fahrenheit" ? _convertCelsiusToFahrenheit : parseFloat;
let HeatingThresholdCharacteristic = service.getCharacteristic(this.Characteristic.HeatingThresholdTemperature);
HeatingThresholdCharacteristic.setProps({
minValue: thisMinTemp,
maxValue: thisMaxTemp,
minStep: thisMinStep
});
addNumericSensorActorCharacteristicWithDistinctTransformation.bind(this)(service,
HeatingThresholdCharacteristic,
{item: CLIMATE_CONFIG.heatingThresholdTempItem},
setTransformation,
getTransformation,
optional
);
}
//edit
function addRelativeHumidityDehumidifierThresholdCharacteristic(service, optional) {
addNumericSensorActorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.RelativeHumidityDehumidifierThreshold), {item: CLIMATE_CONFIG.dehumidifierThresholdItem}, optional);
}
function addRelativeHumidityHumidifierThresholdCharacteristic(service, optional) {
addNumericSensorActorCharacteristic.bind(this)(service, service.getCharacteristic(this.Characteristic.RelativeHumidityHumidifierThreshold), {item: CLIMATE_CONFIG.humidifierThresholdItem}, optional);
}
function addTemperatureDisplayUnitsCharacteristic(service) {
switch (this._config[CLIMATE_CONFIG.tempUnit]) {
default:
case 'Celsius':
this._tempUnit = this.Characteristic.TemperatureDisplayUnits.CELSIUS;
break;
case 'Fahrenheit':
this._tempUnit = this.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
break;
}
service.getCharacteristic(this.Characteristic.TemperatureDisplayUnits)
.setValue(this._tempUnit);
}
module.exports = {
addWaterLevelCharacteristic,
addRotationSpeedCharacteristic,
addCurrentRelativeHumidityCharacteristic,
addCurrentTemperatureCharacteristic,
addCoolingThresholdCharacteristic,
addHeatingThresholdCharacteristic,
addTemperatureDisplayUnitsCharacteristic,
addTargetRelativeHumidityCharacteristic,
addTargetTemperatureCharacteristic,
addRelativeHumidityDehumidifierThresholdCharacteristic,
addRelativeHumidityHumidifierThresholdCharacteristic
};
I'm fighting with this problem for quite some time now, it only allows temp between 0 and 35 so the values must be hardcoded somewhere, recall there was also a typo for fan speed in Climate.js. Will give a try of your workaround, thanks!
@kanivaloss could you please open a pull request with your proposed changes? happy to review and merge upstream!
@maisun This is part of the default characteristics...
See here. I am not sure if we can overwrite those with arbitrary numbers or if there is another check on HK side....
@maisun This is part of the default characteristics...
See here. I am not sure if we can overwrite those with arbitrary numbers or if there is another check on HK side.... @steilerDev, I can confirm @kanivaloss's fix works for me, tested with success. Also I'd like to point a typo in line 48:
rotationSpeedCharacteristic.setProps({ minValue: thisMinSpeed, maxValue: thisMaxSpeed, minTempStep: thisMinStep //Should be minStep instead });
@maisun @kanivaloss If this is confirmed to be working, please open a PR so I can merge it into a future release :) Thank you!