Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Honeywell Total Comfort Control API #47

Open
thechrisreese opened this issue Jul 21, 2016 · 4 comments
Open

Honeywell Total Comfort Control API #47

thechrisreese opened this issue Jul 21, 2016 · 4 comments

Comments

@thechrisreese
Copy link

My current setup -

Older Honeywell Thermostats using Redlink Gateway to Total Comfort Control API

Homebridge (running on Mac) sends commands to Wink Hub which sends commands to Total Comfort Control API.

So if I use Siri here is what works:
"Siri, what is the LIVING ROOM AC temperature?"

However, it stops working after that. If I say "Siri, set LIVING ROOM AC to 75 degrees" it will send the command to the Wink Hub. The Wink Hub will change the temperature and then poll the API. But rather than update the Total Comfort Control to the desired temperature, it defaults the Wink Hub back to the current Thermostat settings. Thus the Homebridge to Wink set up works but something happens with Wink calling the API through this process.

When I change settings with just the Wink app, the commands process as expected. So this is something to do with the Homebridge script, or how the Wink Hub interprets what the HomeKit command says from Homebridge.

@thechrisreese
Copy link
Author

I am using the Android credentials. Maybe it is related to that?

@thechrisreese
Copy link
Author

I can have Siri / Home App set the state for COOL / HEAT / AUTO / OFF and that works fine. But Setting a temperature still shows up on the Wink App and immediately reverts back to the previous setting.

@thechrisreese
Copy link
Author

IOS 10 GM

Running Homebridge and Homebridge-Wink for Thermostats

IOS 10 Home app can see the Thermostats, read the State, read the Current Temperature, and read the Target Temperature

However, when I try to change the temperature the Console shows a successful change, the wink App briefly flashes the change, then reverts back immediately.

@thechrisreese
Copy link
Author

Boom, this works -

var inherits = require('util').inherits;

var WinkAccessory, Accessory, Service, Characteristic, uuid;

/*

  • Thermostat Accessory
    */

module.exports = function (oWinkAccessory, oAccessory, oService, oCharacteristic, ouuid) {
if (oWinkAccessory) {
WinkAccessory = oWinkAccessory;
Accessory = oAccessory;
Service = oService;
Characteristic = oCharacteristic;
uuid = ouuid;

    inherits(WinkThermostatAccessory, WinkAccessory);
    WinkThermostatAccessory.prototype.loadData = loadData;
    WinkThermostatAccessory.prototype.deviceGroup = 'thermostats';
}
return WinkThermostatAccessory;

};
module.exports.WinkThermostatAccessory = WinkThermostatAccessory;

function WinkThermostatAccessory(platform, device) {
WinkAccessory.call(this, platform, device, device.thermostat_id);

var that = this;

//Handle the Current State
this
    .addService(Service.Thermostat)
    .getCharacteristic(Characteristic.CurrentHeatingCoolingState)
    .on('get', function (callback) {
        if (that.device.last_reading.powered) { //I need to verify this changes when the thermostat clicks on.
            switch (that.device.last_reading.mode) {
                case "cool_only":
                    callback(null, Characteristic.CurrentHeatingCoolingState.COOL);
                    break;
                case "heat_only":
                    callback(null, Characteristic.CurrentHeatingCoolingState.HEAT);
                    break;
                case "auto": //HomeKit only accepts HEAT/COOL, so we have to determine if we are Heating or Cooling.
                    if (that.device.last_reading.temperature < that.device.last_reading.min_set_point)
                        callback(null, Characteristic.CurrentHeatingCoolingState.HEAT);
                    else
                        callback(null, Characteristic.CurrentHeatingCoolingState.COOL);
                    break;
                case "aux": //This assumes aux is always heat. Wink doesn't support aux with my thermostat even though I have aux mode, so I'm not 100%.
                    callback(null, Characteristic.CurrentHeatingCoolingState.HEAT);
                    break;
                default: //The above list should be inclusive, but we need to return something if they change stuff.
                    callback(null, Characteristic.CurrentHeatingCoolingState.OFF);
                    break;
            }
        } else //For now, powered being false means it is off
            callback(null, Characteristic.CurrentHeatingCoolingState.OFF);
    });

//Handle the Target State
//Handle the Current State
this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TargetHeatingCoolingState)
    .on('get', function (callback) {
        if (that.device.desired_state.powered) { //I need to verify this changes when the thermostat clicks on.
            switch (that.device.desired_state.mode) {
                case "cool_only":
                    callback(null, Characteristic.TargetHeatingCoolingState.COOL);
                    break;
                case "heat_only":
                    callback(null, Characteristic.TargetHeatingCoolingState.HEAT);
                    break;
                case "auto":
                    callback(null, Characteristic.TargetHeatingCoolingState.AUTO);
                    break;
                case "aux": //This assumes aux is always heat. Wink doesn't support aux with my thermostat even though I have aux mode, so I'm not 100%.
                    callback(null, Characteristic.TargetHeatingCoolingState.HEAT);
                    break;
                default: //The above list should be inclusive, but we need to return something if they change stuff.
                    callback(null, Characteristic.TargetHeatingCoolingState.OFF);
                    break;
            }
        } else //For now, powered being false means it is off
            callback(null, Characteristic.TargetHeatingCoolingState.OFF);
    })
    .on('set', function (value, callback) {
        switch (value) {
            case Characteristic.TargetHeatingCoolingState.COOL:
                that.updateWinkProperty(callback, ["mode", "powered"], ["cool_only", true]);
                break;
            case Characteristic.TargetHeatingCoolingState.HEAT:
                that.updateWinkProperty(callback, ["mode", "powered"], ["heat_only", true]);
                break;
            case Characteristic.TargetHeatingCoolingState.AUTO:
                that.updateWinkProperty(callback, ["mode", "powered"], ["auto", true]);
                break;
            case Characteristic.TargetHeatingCoolingState.OFF:
                that.updateWinkProperty(callback, "powered", false);
                break;
        }
    });

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.CurrentTemperature)
    .on('get', function (callback) {
        callback(null, that.device.last_reading.temperature);
    });

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TargetTemperature)
    .on('get', function (callback) {
        if (Characteristic.CurrentHeatingCoolingState.HEAT)
            callback(null, that.device.desired_state.max_set_point);
        else
            callback(null, that.desired_state.desired_state.min_set_point);
    })
    .on('set', function (value, callback) {
        if (Characteristic.CurrentHeatingCoolingState.HEAT)
            that.updateWinkProperty(callback, "max_set_point", value);
        else
            that.updateWinkProperty(callback, "min_set_point", value);
    });

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TemperatureDisplayUnits)
    .on('get', function (callback) {
        if (platform.temperature_unit == "C")
            callback(null, Characteristic.TemperatureDisplayUnits.CELSIUS);
        else
            callback(null, Characteristic.TemperatureDisplayUnits.FAHRENHEIT);
    });

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.HeatingThresholdTemperature)
    .on('get', function (callback) {
        callback(null, that.device.last_reading.min_set_point);
    })
    .on('set', function (value, callback) {
        that.updateWinkProperty(callback, "min_set_point", value);
    });

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.CoolingThresholdTemperature)
    .on('get', function (callback) {
        callback(null, that.device.last_reading.max_set_point);
    })
    .on('set', function (value, callback) {
        that.updateWinkProperty(callback, "max_set_point", value);
    });

if (that.device.last_reading.humidity !== undefined)
    this
        .getService(Service.Thermostat)
        .getCharacteristic(Characteristic.CurrentRelativeHumidity)
        .on('get', function (callback) {
            callback(null, that.device.last_reading.humidity);
        });

//Track the Battery Level
if (that.device.last_reading.battery !== undefined) {
    this.addService(Service.BatteryService)
        .getCharacteristic(Characteristic.BatteryLevel)
        .on('get', function (callback) {
            callback(null, Math.floor(that.device.last_reading.battery * 100));
        });

    this.getService(Service.BatteryService)
        .getCharacteristic(Characteristic.StatusLowBattery)
        .on('get', function (callback) {
            if (that.device.last_reading.battery < 0.25)
                callback(null, Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
            else
                callback(null, Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
        });

    this.getService(Service.BatteryService)
        .setCharacteristic(Characteristic.ChargingState, Characteristic.ChargingState.NOT_CHARGING);
}
//End Battery Level Tracking

this.loadData();

}

var loadData = function () {
this
.getService(Service.Thermostat)
.getCharacteristic(Characteristic.CurrentHeatingCoolingState)
.getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TargetHeatingCoolingState)
    .getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.CurrentTemperature)
    .getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TargetTemperature)
    .getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.TemperatureDisplayUnits)
    .getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.HeatingThresholdTemperature)
    .getValue();

this
    .getService(Service.Thermostat)
    .getCharacteristic(Characteristic.CoolingThresholdTemperature)
    .getValue();


if (this.device.last_reading.humidity !== undefined)
    this
        .getService(Service.Thermostat)
        .getCharacteristic(Characteristic.CurrentRelativeHumidity)
        .getValue();

if (this.device.last_reading.battery !== undefined) {
    this.getService(Service.BatteryService)
        .getCharacteristic(Characteristic.BatteryLevel)
        .getValue();
    this.getService(Service.BatteryService)
        .getCharacteristic(Characteristic.StatusLowBattery)
        .getValue();
}

};

//Service.Thermostat = function(displayName, subtype) {
//Service.call(this, displayName, '0000004A-0000-1000-8000-0026BB765291', subtype);

// Required Characteristics
// this.addCharacteristic(Characteristic.CurrentHeatingCoolingState);
// this.addCharacteristic(Characteristic.TargetHeatingCoolingState);
//this.addCharacteristic(Characteristic.CurrentTemperature);
//this.addCharacteristic(Characteristic.TargetTemperature);
//this.addCharacteristic(Characteristic.TemperatureDisplayUnits);

// Optional Characteristics
// this.addOptionalCharacteristic(Characteristic.CurrentRelativeHumidity);
// this.addOptionalCharacteristic(Characteristic.TargetRelativeHumidity);
// this.addOptionalCharacteristic(Characteristic.CoolingThresholdTemperature);
// this.addOptionalCharacteristic(Characteristic.HeatingThresholdTemperature);
// this.addOptionalCharacteristic(Characteristic.Name);

//inherits(Service.Thermostat, Service);

//Service.Thermostat.UUID = '0000004A-0000-1000-8000-0026BB765291';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant