I think I'm close to getting my thermostat to work but something is not quite right. When I add the device with the ios home app it ends up saying the device could not be added. It has been 2.5yrs since anyone posted on this topic but if anyone out there that is smarter than me could take a look at this code and spot what is wrong please do. I know there is some unused code still in here from the example I started with but I was ignoring it for now thinking it does not matter.
#include "ThermostatAccessoryBase.h"
#include "HKConnection.h"
#include "HKLog.h"
#include <set>
#include <Particle.h>
void ThermostatAccessoryBase::Identify(bool oldValue, bool newValue, HKConnection *sender) {
hkLog.info("Start Identify\n");
}
std::string ThermostatAccessoryBase::getCurrentMode (HKConnection *sender) {
return format("%d",1);
}
std::string ThermostatAccessoryBase::getTargetMode (HKConnection *sender) {
return format("%d",1);
}
void ThermostatAccessoryBase::setTargetMode (int oldValue, int newValue, HKConnection *sender) {
newValue;
}
std::string ThermostatAccessoryBase::getCurrentTemperature (HKConnection *sender) {
return format("%.1f", 71.1);
}
std::string ThermostatAccessoryBase::getTargetTemperature (HKConnection *sender) {
return format("%.1f", 72.2);
}
void ThermostatAccessoryBase::setTargetTemperature (float oldValue, float newValue, HKConnection *sender) {
newValue;
}
std::string ThermostatAccessoryBase::getTemperatureUnit (HKConnection *sender) {
return format("%d",1);
}
void ThermostatAccessoryBase::setTemperatureUnit (int oldValue, int newValue, HKConnection *sender) {
newValue;
}
void ThermostatAccessoryBase::initAccessorySet() {
Accessory *ThermostatAcc1 = new Accessory();
//Add thermostat
AccessorySet *accSet = &AccessorySet::getInstance();
addInfoServiceToAccessory(ThermostatAcc1, "Thermostat name", "Vendor name", "Model name", "1","1.0.0", std::bind(&ThermostatAccessoryBase::Identify, this, std::placeholders::_1, std::placeholders::_2,std::placeholders::_3));
accSet->addAccessory(ThermostatAcc1);
Service *ThermostatService1 = new Service(serviceType_thermostat);
ThermostatAcc1->addService(ThermostatService1);
intCharacteristics *currentModeStateChar = new intCharacteristics(charType_currentHeatCoolMode, permission_read|permission_notify, 0, 2, 1, unit_none);
currentModeStateChar->perUserQuery = std::bind(&ThermostatAccessoryBase::getCurrentMode, this, std::placeholders::_1);
ThermostatAcc1->addCharacteristics(ThermostatService1, currentModeStateChar);
intCharacteristics *targetModeStateChar = new intCharacteristics(charType_targetHeatCoolMode, permission_read|permission_write|permission_notify, 0, 3, 1, unit_none);
targetModeStateChar->perUserQuery = std::bind(&ThermostatAccessoryBase::getTargetMode, this, std::placeholders::_1);
targetModeStateChar->valueChangeFunctionCall = std::bind(&ThermostatAccessoryBase::setTargetMode, this, std::placeholders::_1, std::placeholders::_2,std::placeholders::_3);
ThermostatAcc1->addCharacteristics(ThermostatService1, targetModeStateChar);
floatCharacteristics *currentTemperatureChar = new floatCharacteristics(charType_currentTemperature, permission_read|permission_notify, 0, 100, 0.1, unit_celsius);
currentTemperatureChar->perUserQuery = std::bind(&ThermostatAccessoryBase::getCurrentTemperature, this, std::placeholders::_1);
ThermostatAcc1->addCharacteristics(ThermostatService1, currentTemperatureChar);
floatCharacteristics *targetTemperatureChar = new floatCharacteristics(charType_targetTemperature, permission_read|permission_write|permission_notify, 0, 38, 0.1, unit_celsius);
targetTemperatureChar->perUserQuery = std::bind(&ThermostatAccessoryBase::getTargetTemperature, this, std::placeholders::_1);
targetTemperatureChar->valueChangeFunctionCall = std::bind(&ThermostatAccessoryBase::setTargetTemperature, this, std::placeholders::_1, std::placeholders::_2,std::placeholders::_3);
ThermostatAcc1->addCharacteristics(ThermostatService1, targetTemperatureChar);
intCharacteristics *temperatureUnitChar = new intCharacteristics(charType_temperatureUnit, permission_read, 0, 1, 1, unit_none);
temperatureUnitChar->perUserQuery = std::bind(&ThermostatAccessoryBase::getTemperatureUnit, this, std::placeholders::_1);
ThermostatAcc1->addCharacteristics(ThermostatService1, temperatureUnitChar);
};
RgbColor ThermostatAccessoryBase::HsvToRgb(HsvColor hsv)
{
RgbColor rgb;
unsigned char region, remainder, p, q, t;
if (hsv.s == 0)
{
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
region = hsv.h / 43;
remainder = (hsv.h - (region * 43)) * 6;
p = (hsv.v * (255 - hsv.s)) >> 8;
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
switch (region)
{
case 0:
rgb.r = hsv.v; rgb.g = t; rgb.b = p;
break;
case 1:
rgb.r = q; rgb.g = hsv.v; rgb.b = p;
break;
case 2:
rgb.r = p; rgb.g = hsv.v; rgb.b = t;
break;
case 3:
rgb.r = p; rgb.g = q; rgb.b = hsv.v;
break;
case 4:
rgb.r = t; rgb.g = p; rgb.b = hsv.v;
break;
default:
rgb.r = hsv.v; rgb.g = p; rgb.b = q;
break;
}
return rgb;
}
HsvColor ThermostatAccessoryBase::RgbToHsv(RgbColor rgb)
{
HsvColor hsv;
unsigned char rgbMin, rgbMax;
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
hsv.v = rgbMax;
if (hsv.v == 0)
{
hsv.h = 0;
hsv.s = 0;
return hsv;
}
hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
if (hsv.s == 0)
{
hsv.h = 0;
return hsv;
}
if (rgbMax == rgb.r)
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
else if (rgbMax == rgb.g)
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
else
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
return hsv;
}