Closed daz closed 3 years ago
Hi daz,
You should make homekit can set cooling status, temperature and temperature unit.
here is mine thermostat definitions.
// Thermostat Service, HOMEKIT_SERVICE_THERMOSTAT homekit_characteristic_t h_thermo_c_st = HOMEKIT_CHARACTERISTIC_(CURRENT_HEATING_COOLING_STATE, 0); homekit_characteristic_t h_thermo_t_st = HOMEKIT_CHARACTERISTIC_(TARGET_HEATING_COOLING_STATE, 0, .getter = get_target_heating_cooling_state, .setter = set_target_heating_cooling_state); homekit_characteristic_t h_thermo_c_temp = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0); homekit_characteristic_t h_thermo_t_temp = HOMEKIT_CHARACTERISTIC_(TARGET_TEMPERATURE, 0, .getter = get_target_temperature, .setter = set_target_temperature); homekit_characteristic_t h_thermo_temp_unit = HOMEKIT_CHARACTERISTIC_(TEMPERATURE_DISPLAY_UNITS, 0, .getter = get_temperature_display_unit, .setter = set_temperature_display_unit); homekit_characteristic_t h_thermo_c_humi = HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0);
also you can check whole codes as following my code.
https://github.com/waaraawa/Homekit_AQI_Desk/blob/master/homekit_config.c
BR
When adding the setters/getters I'm still getting an error "Accessory is out of compliance".
Same error when I copy your code verbatim. But when I remove this section, it pairs:
HOMEKIT_SERVICE(
THERMOSTAT,
.primary = true,
.characteristics = (homekit_characteristic_t*[]) {
HOMEKIT_CHARACTERISTIC(NAME, "Air Conditioner"),
&h_thermo_c_st,
&h_thermo_t_st,
&h_thermo_c_temp,
&h_thermo_t_temp,
&h_thermo_temp_unit,
&h_thermo_c_humi,
NULL
}
),
@daz If you can share your homekit_config.c file, I can review it but I don't know why with not enought info. I hope you review which info you should make get/set as characteristics.h
`/** Defines that the accessory contains a thermostat.
Required Characteristics:
TEMPERATURE_DISPLAY_UNITS
Optional Characteristics:
Okay I found the problem, the default target temperature variable was zero, which is out of range.
Okay I found the problem, the default target temperature variable was zero, which is out of range.
I had a similar problem with the CURRENT_TEMPERATURE. However for me, the issue wasn't with the default value (I had it correctly set to 20).
My CURRENT_TEMPERATURE value was being overwritten by a temperature sensor's values, and at the time of pairing with Homekit, the sensor was unplugged and setting CURRENT_TEMPERATURE to a value outside of the "acceptable" temperature range defined by Apple.
Hopefully this helps someone in the future if they are ever in the situation I was in.
Hey guys,
im struggling with creating a thermostat also - either it doesnt pair or im getting stuck on "updating" state.
Can someone provide a working example of how they setup their thermostat using this library?
Any help is much appreciated!
Currently i have the following code:
`#include <homekit/homekit.h>
void my_accessory_identify(homekit_value_t _value) { printf("accessory identify\n"); }
// celsius homekit_characteristic_t ac_display_units = HOMEKITCHARACTERISTIC(TEMPERATURE_DISPLAY_UNITS, 0);
// float; min 0, max 100, step 0.1, unit celsius homekit_characteristic_t ac_current_temp = HOMEKITCHARACTERISTIC(CURRENT_TEMPERATURE, 20);
// float; min 0, max 100, step 0.1, unit celsius homekit_characteristic_t ac_target_temp = HOMEKITCHARACTERISTIC(TARGET_TEMPERATURE, 20);
// 0: Off, 1: Heat, 2: Cool homekit_characteristic_t ac_current_state = HOMEKITCHARACTERISTIC(CURRENT_HEATING_COOLING_STATE, 0);
// 0: off, 1: heat, 2:cool, 3: auto homekit_characteristic_t ac_target_state = HOMEKITCHARACTERISTIC(CURRENT_HEATING_COOLING_STATE, 0);
homekit_accessory_t accessories[] = { HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_thermostat, .services=(homekit_service_t[]) { HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t[]) { HOMEKIT_CHARACTERISTIC(NAME, "AIR CON"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "korgoth"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0000002"), HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266"), //HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.0.2"), HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify), NULL }), HOMEKIT_SERVICE(THERMOSTAT, .primary=true, .characteristics=(homekit_characteristic_t[]) { &ac_display_units, &ac_current_temp, &ac_target_temp, &ac_current_state, &ac_target_state, //&ac_active, //&ac_rotation_speed, NULL }), NULL }), NULL };
homekit_server_config_t config = { .accessories = accessories, .password = "123-45-678", };`
and for the sketch itself:
`#include
//temperature sensor output pin int temp_outputpin = A0;
// IR settings const uint16_t kIrLed = 14; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRHitachiAc296 ac(kIrLed); // Set the GPIO to be used to sending the message
// Globals bool queueCommand = false; void flipQueueCommand(bool newState) { Serial.write("Flipping queueCommand to %d\n", newState); queueCommand = newState; }
void setup() { Serial.begin(115200); wifi_connect(); // in wifi_info.h
homekit_storage_reset(); // to remove the previous HomeKit pairing storage when you first run this new HomeKit example
my_homekit_setup();
//ac_rotation_speed.value.int_value = 100; Serial.write("HomeKit setup complete. About to start ac.begin()\n"); ac.begin(); }
void loop() { drd.loop(); my_homekit_loop(); delay(10);
if (queueCommand) { Serial.write("Sending AC Command....\n"); ac.send(); flipQueueCommand(false); } }
// defined in my_accessory.c extern "C" homekit_server_config_t config;
extern "C" homekit_characteristic_t ac_display_units; extern "C" homekit_characteristic_t ac_current_temp; extern "C" homekit_characteristic_t ac_target_temp; extern "C" homekit_characteristic_t ac_current_state; extern "C" homekit_characteristic_t ac_target_state;
static uint32_t next_heap_millis = 0;
void target_temp_setter(const homekit_value_t value) { LOG_D("TARGET TEMP SETTER: Got value: %f", value.float_value); ac_target_temp.value = value; //sync value
ac.setMode(ac.getMode()); ac.setTemp(value.float_value); flipQueueCommand(true); }
void target_state_setter(const homekit_value_t value) { LOG_D("TARGET STATE SETTER: Got value INT: %d", value.int_value); ac_target_state.value = value; //sync value
switch(value.int_value) {
case 0:
ac.off();
break;
case 1:
ac.setMode(MODE_HEAT);
break;
case 2:
ac.setMode(MODE_COOL);
break;
case 3:
ac.setMode(MODE_AUTO);
break;
}
flipQueueCommand(true);
}
void current_state_setter(const homekit_value_t value) { LOG_D("CURRENT STATE SETTER NO OP: Got value INT: %d", value.int_value); ac_target_state.value = value; //sync value }
// --- End Setters
// --- GETTERS homekit_value_t current_state_getter() { LOG_D("CURRENT STATE GETTER CALLED! RESPONDING WITH: %d", ac_target_state.value.int_value); return HOMEKIT_UINT8(ac_current_state.value.int_value); }
homekit_value_t target_state_getter() { LOG_D("TARGET STATE GETTER CALLED! RESPONDING WITH: %d", ac_target_state.value.int_value); return HOMEKIT_UINT8(ac_target_state.value.int_value); }
homekit_value_t target_temp_getter() { LOG_D("TARGET TEMP GETTER CALLED! RESPONDING WITH: %f", ac_target_temp.value.float_value); return ac_target_temp.value; }
// END GETTERS
void my_homekit_setup() { Serial.write("starting my_homekit_setup\n");
//ac_active.setter = active_setter; ac_current_state.getter = current_state_getter; ac_current_state.setter = current_state_setter; ac_target_state.setter = target_state_setter; ac_target_state.getter = target_state_getter; ac_target_temp.setter = target_temp_setter; ac_target_temp.getter = target_temp_getter; //ac_rotation_speed.setter = rotation_speed_setter;
Serial.write("about to call arduino_homekit_setup\n"); arduino_homekit_setup(&config);
//report the switch value HERE to HomeKit if it is changed (e.g. by a physical button)
Serial.write("exiting my_homekit_setup\n"); }
void my_homekit_loop() { arduino_homekit_loop(); const uint32_t t = millis(); if (t > next_heap_millis) { next_heap_millis = t + 10 * 1000; my_homekit_report(); LOG_D("Free heap: %d, HomeKit clients: %d", ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
} }
void my_homekit_report() { //report current temperature int analogValue = analogRead(temp_outputpin); float millivolts = (analogValue/1024.0) * 3300; //3300 is the voltage provided by NodeMCU float celsius = millivolts/10; //LOG_D("Current temperature: %.1f", celsius); ac_current_temp.value.float_value = celsius; homekit_characteristic_notify(&ac_current_temp, ac_current_temp.value);
} `
look it in your code: HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_thermostat, .services=(homekit_service_t[]) { HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_thermostat, .services=(homekit_service_t*[]) {
All other accessories and examples I try work fine, but thermostat is giving me the error.
Any ideas?