Closed leotordo closed 9 months ago
You have to call hap_char_update_val() API to update the characteristic's value and also report it to the HomeKit controllers.
You can find sample usage in the smart_outlet example here.
Thank you. I'll try ASAP and I'll turn here whit results regards
Hello, I wrote this code
while(1)
{
if(!gpio_get_level(GPIO_NUM_9))
{
lightbulb_set_brightness(50);
hap_val_t appliance_value = { .i = 50, };
hap_char_t *outlet_in_use = hap_serv_get_char_by_uuid(service, HAP_CHAR_UUID_BRIGHTNESS);
hap_char_update_val(outlet_in_use, &appliance_value);
}
}
The application starts with 10% of PWM
ret |= hap_serv_add_char(service, hap_char_brightness_create(10));
if I press GPIO9 switch the led brightness changes but the Home app remains at 10%
Where's the problem? Thanks Andrea
Brief update. The position of my code is at the end of the thread _lightbulb_threadentry I added a single shot code for the button
/* Enable Hardware MFi authentication (applicable only for MFi variant of SDK) */
hap_enable_mfi_auth(HAP_MFI_AUTH_HW);
/* Initialize Wi-Fi */
app_wifi_init();
/* After all the initializations are done, start the HAP core */
hap_start();
/* Start Wi-Fi */
app_wifi_start(portMAX_DELAY);
hap_val_t appliance_value = { .i = 50, };
hap_char_t *outlet_in_use = hap_serv_get_char_by_uuid(service, HAP_CHAR_UUID_BRIGHTNESS);
int first=0;
while(1)
{
if(!gpio_get_level(GPIO_NUM_9) && first==0)
{
first=1;
lightbulb_set_brightness(50);
hap_char_update_val(outlet_in_use, &appliance_value);
}
if(gpio_get_level(GPIO_NUM_9) && first==1)
{
first=0;
vTaskDelay(pdMS_TO_TICKS(300));
}
}
/* The task ends here. The read/write callbacks will be invoked by the HAP Framework */
vTaskDelete(NULL);
light_err: hap_acc_delete(accessory); vTaskDelete(NULL); }
and...doesn't work :-( Thanks Andrea
@leotordo can you try adding prints to see if your code is reaching those lines? Additionally, it will be better to have a vTaskDelay(300/portTICK_PERIOD_MS); in your while(1) loop, outside the if conditions to prevent this task from consuming resources continuously.
lightbulb_set_brightness has prints I added a print after hap_char_update_val (see below)
On the terminal I've these logs
Events Enabled for aid=1 iid=15 Events Enabled for aid=1 iid=17 Events Enabled for aid=1 iid=19 Events Enabled for aid=1 iid=20 Events Enabled for aid=1 iid=21
If I change from iPhone I've this output
if I press mechanical switch I get
"Value Changed" doesn't appear....and the iPhone is not updated
while(1)
{
vTaskDelay(pdMS_TO_TICKS(300));
if(!gpio_get_level(GPIO_NUM_9) && first==0)
{
first=1;
lightbulb_set_brightness(50);
appliance_value.i=50;
hap_char_update_val(outlet_in_use, &appliance_value);
ESP_LOGI(TAG, "hap_char_update_val SENT");
}
if(gpio_get_level(GPIO_NUM_9) && first==1)
{
first=0;
vTaskDelay(pdMS_TO_TICKS(300));
}
}
I added the print of the returned value of hap_char_update_val
the error is -1
A couple of points
hap_serv_get_char_by_uuid(service, HAP_CHAR_UUID_BRIGHTNESS)
is indeed giving you a valid pointer. If you are using the lightbulb example directly, you will see here that the service pointer gets over-riden with a different service: service = hap_serv_fw_upgrade_create(&ota_config);
if (!service) {
ESP_LOGE(TAG, "Failed to create Firmware Upgrade Service");
goto light_err;
}
hap_acc_add_serv(accessory, service);
You can remove this snippet or use a different service pointer here.
hap_char_update_val(outlet_in_use, &appliance_value)
. If the value stays the same, no notification will be triggered.thank you. On monday I'll check your points. Have a nice w/end
hello. Issue solved. You're right, the problem was on service = hap_serv_fw_upgrade_create(&ota_config);
I defined service2 instead of service and my routine works.
I'll keep in mind also your suggestion about using different values.
Thanks I close this issue Regards
Hi,
Basically I hit the similar issue with not reflecting accessory status in Apple iPhone's HomeKit.
And I checked that with out of the box smart_outlet
from the examples.
Here is a diff of app_main.c
- I've applied some stupid counter to bypass the double edge issue (state is changed twice every time we hit a push button there). This push button ISR is not a case here, so let's move on.
+static int counter = 0;
+static bool new_value = false;
+
static QueueHandle_t s_esp_evt_queue = NULL;
/**
* @brief the recover outlet in use gpio interrupt function
@@ -162,6 +166,7 @@ static void smart_outlet_thread_entry(void *p)
/* Create the Outlet Service. Include the "name" since this is a user visible service */
service = hap_serv_outlet_create(false, false);
+
hap_serv_add_char(service, hap_char_name_create("My Smart Outlet"));
/* Get pointer to the outlet in use characteristic which we need to monitor for state changes */
@@ -227,10 +232,16 @@ static void smart_outlet_thread_entry(void *p)
if (xQueueReceive(s_esp_evt_queue, &io_num, portMAX_DELAY) == pdFALSE) {
ESP_LOGI(TAG, "Outlet-In-Use trigger FAIL");
} else {
- appliance_value.b = gpio_get_level(io_num);
+ counter+=1;
+ if (counter % 3 == 0) {
+ new_value = !new_value;
+ appliance_value.b = new_value;
+ hap_char_update_val(outlet_in_use, &appliance_value);
+ ESP_LOGI(TAG, "Outlet-In-Use triggered [%d]", appliance_value.b);
+ }
+
/* If any state change is detected, update the Outlet In Use characteristic value */
- hap_char_update_val(outlet_in_use, &appliance_value);
- ESP_LOGI(TAG, "Outlet-In-Use triggered [%d]", appliance_value.b);
+
}
}
}
As you can see, it does not modify anything around services nor characteristics. And it is simply not working. When I toggle state via push button, the state change is not reflected in the HomeKit iPhone app.
With a DUPA
approach (Debug Using Printable ASCII) I ended up printing HTTP messages sent out from the device and noticed I've got two characteristics assigned to one service. iid 12
and iid 13
. So far so good.
outlet_in_use
uses "13". So I changed it to 12
in the HTTP Message that is sent towards a controller (iPhone's HomeKit) and suddenly, as you can guess - status is reflected.
After all I modified the exemplary code in that endless loop with this:
hap_char_update_val(hap_serv_get_char_by_uuid(service, HAP_CHAR_UUID_ON), &appliance_value);
which eventually means that I am sending status update over "ON" characteristics and the status change is reflected in the iPhone's HomeKit web interface (without pushing app to background nor restarting)
Which is weird and I can't wait for comments. Regards
Hello everybody. I've got esp-homekit-sdk from Espressif and I built the example "lightbulb". It works fine. I can change led status from may Home App.
Now, I want to switch on/off the led also by a mechanical switch. I modified the code for reading a GPIO input connected to this switch. I works, but the iPhone doesn't sense the status changed
How to send the changed status notification to the main task?
Thanks Andrea