Open DirkRussellG opened 3 years ago
Even I would like help with this one
Oh I see, this is for "issues" (like it plainly states), not for novices getting help understanding the coding, my ignorance, my apologies
Sure, you can ask for help as a novice. That is not a problem at all. There is a huge difference between a novice asking for help and someone that just dumps its questions on the web and expects others to solve it for them.
Please provide any relevant code so others can look at it and help you. The part of code that you added to this issue is not even related to the question. Or maybe it is, but than the question is unclear to me. I assume that you have to set it up as a BRIDGE accessory and add 2 characteristics for each individual switch with a corresponding value_t object attached to it. Each single value should be able to be read from and written to. So please, reword your question. People are willing to help.
My objective is to use one esp8266 for 2 individually controlled relays. I added a second id (.id=2) in the my_accessory.c file and it shows up ok in the Home app. I have not figured out how read the variable properly as to identify what switch was pressed. After that I assume its a simple IF statement to the code section I posted as to which pin to apply the changes to.
You have to wire an additional homekit_characteristic_t to your configuration like so:
homekit_characteristic_t cha_switch_1 = HOMEKIT_CHARACTERISTIC_(ON, false);
homekit_characteristic_t cha_switch_2 = HOMEKIT_CHARACTERISTIC_(ON, false);
homekit_accessory_t *accessories[] = {
HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
---- left out for clarity -------
}),
HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "Switch 1"),
&cha_switch_1,
NULL
}),
NULL
}),
HOMEKIT_ACCESSORY(.id=2, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
---- left out for clarity -------
}),
HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "Switch 2"),
&cha_switch_2,
NULL
}),
NULL
}),
NULL
};
In your 'my_homekit_setup' function you can attach the setter method to each of these 2 values:
cha_switch_1.setter = cha_switch_1_setter;
cha_switch_2.setter = cha_switch_2_setter;
woaw... markup is not that easy here...
Thank you. I think I can follow that. I wrongly thought the additional ID was instance of the main accessory, like an array or something. Can I post the finished code as an example? I know other novices like me would be interested.
Thanks sircuri, works. Thank you.
`/*
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(); }
void loop() { my_homekit_loop(); delay(10); }
//============================== // HomeKit setup and loop //==============================
// access your HomeKit characteristics defined in my_accessory.c extern "C" homekit_server_config_t config; extern "C" homekit_characteristic_t cha_switch_1; extern "C" homekit_characteristic_t cha_name_1; extern "C" homekit_characteristic_t cha_switch_2; extern "C" homekit_characteristic_t cha_name_2;
static uint32_t next_heap_millis = 0;
//Called when the switch value is changed by iOS Home APP
void cha_switch_1_setter(const homekit_value_t value) { bool on = value.bool_value; cha_switch_1.value.bool_value = on; //sync the value LOG_D("Switch 1: %s", on ? "ON" : "OFF"); digitalWrite(PIN_SWITCH1, on ? LOW : HIGH); } void cha_switch_2_setter(const homekit_value_t value) { bool on = value.bool_value; cha_switch_2.value.bool_value = on; //sync the value LOG_D("Switch 2: %s", on ? "ON" : "OFF"); digitalWrite(PIN_SWITCH2, on ? LOW : HIGH); }
void my_homekit_setup() { pinMode(PIN_SWITCH1, OUTPUT); digitalWrite(PIN_SWITCH1, HIGH); pinMode(PIN_SWITCH2, OUTPUT); digitalWrite(PIN_SWITCH2, HIGH);
//Add the .setter function to get the switch-event sent from iOS Home APP.
//The .setter should be added before arduino_homekit_setup.
//HomeKit sever uses the .setter_ex internally, see homekit_accessories_init function.
//Maybe this is a legacy design issue in the original esp-homekit library,
//and I have no reason to modify this "feature".
cha_switch_1.setter = cha_switch_1_setter; cha_switch_2.setter = cha_switch_2_setter; arduino_homekit_setup(&config);
//report the switch value to HomeKit if it is changed (e.g. by a physical button)
//bool switch_is_on = true/false;
//cha_switch_on.value.bool_value = switch_is_on;
//homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
}
void my_homekit_loop() { arduino_homekit_loop(); const uint32_t t = millis(); if (t > next_heap_millis) { // show heap info every 5 seconds next_heap_millis = t + 5 * 1000; LOG_D("Free heap: %d, HomeKit clients: %d", ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
}
}`
`/* my_accessory.c Define the accessory in C language using the Macro in characteristics.h
Created on: 2020-05-15
Author: Mixiaoxiao (Wang Bin)
*/
void my_accessory_identify(homekit_value_t _value) { printf("accessory identify\n"); }
// Switch (HAP section 8.38) // required: ON // optional: NAME
// format: bool; HAP section 9.70; write the .setter function to get the switch-event sent from iOS Home APP. homekit_characteristic_t cha_switch_1 = HOMEKITCHARACTERISTIC(ON, false); homekit_characteristic_t cha_switch_2 = HOMEKITCHARACTERISTIC(ON, false);
// format: string; HAP section 9.62; max length 64 homekit_characteristic_t cha_name_1 = HOMEKITCHARACTERISTIC(NAME, "Switch01"); homekit_characteristic_t cha_name_2 = HOMEKITCHARACTERISTIC(NAME, "Switch02");
homekit_accessory_t accessories[] = { HOMEKIT_ACCESSORY(.id = 1, .category = homekit_accessory_category_switch, .services = (homekit_service_t[]) { HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics = (homekit_characteristic_t[]) { HOMEKIT_CHARACTERISTIC(NAME, "Switch01"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Arduino HomeKit"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123456"), HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266/ESP32"), HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"), HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify), NULL }), HOMEKIT_SERVICE(SWITCH, .primary = true, .characteristics = (homekit_characteristic_t[]) { &cha_switch_1, &cha_name_1, NULL }), NULL }), HOMEKIT_ACCESSORY(.id = 2, .category = homekit_accessory_category_switch, .services = (homekit_service_t[]) { HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics = (homekit_characteristic_t[]) { HOMEKIT_CHARACTERISTIC(NAME, "Switch02"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Arduino HomeKit"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123456"), HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266/ESP32"), HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"), HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify), NULL }), HOMEKIT_SERVICE(SWITCH, .primary = true, .characteristics = (homekit_characteristic_t*[]) { &cha_switch_2, &cha_name_2, NULL }), NULL }),
NULL };
homekit_server_config_t config = { .accessories = accessories, .password = "111-11-111" };`
@DirkRussellG my_accessory.c
void my_accessory_identify(homekit_value_t _value) { printf("accessory identify\n"); }
// Switch (HAP section 8.38) // required: ON // optional: NAME
// format: bool; HAP section 9.70; write the .setter function to get the switch-event sent from iOS Home APP. homekit_characteristic_t cha_switch_on1 = HOMEKITCHARACTERISTIC(ON, false); homekit_characteristic_t cha_switch_on2 = HOMEKITCHARACTERISTIC(ON, false); // format: string; HAP section 9.62; max length 64 homekit_characteristic_t cha_name1 = HOMEKITCHARACTERISTIC(NAME, "LED"); homekit_characteristic_t cha_name2 = HOMEKITCHARACTERISTIC(NAME, "Fan");
homekit_accessory_t accessories[] = { HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_lightbulb, .services=(homekit_service_t[]) { HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t[]) { HOMEKIT_CHARACTERISTIC(NAME, "LED"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Arduino HomeKit"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123456"), HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266/ESP32"), HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"), HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify), NULL }), HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t[]){ &cha_switch_on1, &cha_name1, NULL }), NULL }), HOMEKIT_ACCESSORY(.id=2, .category=homekit_accessory_category_fan, .services=(homekit_service_t[]) { HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t[]) { HOMEKIT_CHARACTERISTIC(NAME, "Fan"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Arduino HomeKit"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123457"), HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266/ESP32"), HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"), HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify), NULL }), HOMEKIT_SERVICE(FAN, .primary=true, .characteristics=(homekit_characteristic_t*[]){ &cha_switch_on2, &cha_name2, NULL }), NULL }), NULL };
homekit_server_config_t config = { .accessories = accessories, .password = "222-22-222" };
@DirkRussellG Switch
void setup() { Serial.begin(9600); 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(); }
void loop() { my_homekit_loop(); delay(10); }
//============================== // HomeKit setup and loop //==============================
// access your HomeKit characteristics defined in my_accessory.c extern "C" homekit_server_config_t config; extern "C" homekit_characteristic_t cha_switch_on1; extern "C" homekit_characteristic_t cha_switch_on2; static uint32_t next_heap_millis = 0;
//Called when the switch value is changed by iOS Home APP void cha_switch_on_setter1(const homekit_value_t value) { bool on = value.bool_value; cha_switch_on1.value.bool_value = on; //sync the value LOG_D("Switch: %s", on ? "ON" : "OFF"); digitalWrite(PIN_SWITCH1, on ? HIGH : LOW); } void cha_switch_on_setter2(const homekit_value_t value) { bool on = value.bool_value; cha_switch_on2.value.bool_value = on; //sync the value LOG_D("Switch: %s", on ? "ON" : "OFF"); digitalWrite(PIN_SWITCH2, on ? LOW: HIGH); }
void my_homekit_setup() { pinMode(PIN_SWITCH1, OUTPUT); digitalWrite(PIN_SWITCH1, LOW); pinMode(PIN_SWITCH2, OUTPUT); digitalWrite(PIN_SWITCH2, HIGH); //Add the .setter function to get the switch-event sent from iOS Home APP. //The .setter should be added before arduino_homekit_setup. //HomeKit sever uses the .setter_ex internally, see homekit_accessories_init function. //Maybe this is a legacy design issue in the original esp-homekit library, //and I have no reason to modify this "feature". cha_switch_on1.setter = cha_switch_on_setter1; cha_switch_on2.setter = cha_switch_on_setter2; arduino_homekit_setup(&config);
//report the switch value to HomeKit if it is changed (e.g. by a physical button)
//bool switch_is_on = true/false;
//cha_switch_on.value.bool_value = switch_is_on;
//homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
}
void my_homekit_loop() { arduino_homekit_loop(); const uint32_t t = millis(); if (t > next_heap_millis) { // show heap info every 5 seconds next_heap_millis = t + 5 * 1000; LOG_D("Free heap: %d, HomeKit clients: %d", ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
}
}
@yepkevin612 Thank you so much. Are those changes mainly for proper naming convention? Doesn't change functionality or does it?
Here is my code for the connected physical push button, it works but it will probably give entertainment or a big sigh :-) I'm sure it could be done in just a few lines.
void check_pushbutton_state() {
button1_state = digitalRead(PIN_BUTTON1);
if (button1_state == HIGH) {
if (button1_flag == 0) {
button1_flag = 1; //
}
}
if (button1_state == LOW && button1_flag == 1) { //button released
button1_flag = 0;
boolean readPinState = (digitalRead(PIN_SWITCH1)); //relay is active low
digitalWrite(PIN_SWITCH1, !digitalRead(PIN_SWITCH1));
cha_switch_1.value.bool_value = readPinState;
homekit_characteristic_notify(&cha_switch_1, cha_switch_1.value);
}
button2_state = digitalRead(PIN_BUTTON2);
if (button2_state == HIGH) {
if (button2_flag == 0) {
button2_flag = 1; //
}
}
if (button2_state == LOW && button2_flag == 1) {
button2_flag = 0;
boolean readPinState = (digitalRead(PIN_SWITCH2));
digitalWrite(PIN_SWITCH2, !digitalRead(PIN_SWITCH2));
cha_switch_2.value.bool_value = readPinState;
homekit_characteristic_notify(&cha_switch_2, cha_switch_2.value);
}
}
@DirkRussellG just two ON\OFF switch
@DirkRussellG Do you know the codes ,2 switch with push button ?
I guess I probably don't.
I was looking over the changes you made in the code. Is Serial.begin(9600); preferred over Serial.begin(115200); like in the examples?
@DirkRussellG in example is 115200.
can you share your code with push button?
in the original code I posted it had 115200, in the code you tweaked and reposted it has 9600
@yepkevin612 > can you share your code with push button?
Is this for me? I have my novice button code above.
Maybe a bit late, but I noticed your "password" was "222-22-222", which is explicitly called out in the HAP docs as not allowed. That could be your problem.
Maybe a bit late, but I noticed your "password" was "222-22-222", which is explicitly called out in the HAP docs as not allowed. That could be your problem.
Where in the HAP doco is that specified? I have a "built device" using that password and it is a bit flaky, and I'm wondering... But I've scanned the HomeKit Accessory Protocol Specification (Non-Commercial Version Release R2) document and don't see any prohibitions...
or are you referring to the following line in section 4.2.1.2... The following are examples of setup codes that must not be used due to their trivial, insecure nature:
If so I think that's more of a guideline than a rule. If you build something for commercial distribution and submit it to Apple for validation I'd expect Apple to reject the device, because it's "trivial, insecure nature". But I don't think there is anything in the Spec (or Apples code) that "enforces" that guideline... we user 111-11-1111 in examples all over the place...
Yup, that’s the section I was talking about. You’re clearly correct in that it didn’t actually prevent your device from working, just offering it as a suggestion. When the spec says, “must not be used,” I typically take that to mean, “don’t do it.” I guess in this case you got lucky.
I set up the Switch example on two ESP8266 and it works exactly right for me. Does anyone have any code examples of using one device to setup more than one switch/relay set ? I can see how to set up the my_accessory.c file but I haven't yet seen how to get the cha_name. (maybe just a hint - I've looked through the closed tickets)