main/app_main.c
changeset 2 6c96c21bd8f1
parent 1 289a6264a47e
equal deleted inserted replaced
1:289a6264a47e 2:6c96c21bd8f1
     7 #include <freertos/timers.h>
     7 #include <freertos/timers.h>
     8 #include <freertos/queue.h>
     8 #include <freertos/queue.h>
     9 #include <esp_log.h>
     9 #include <esp_log.h>
    10 #include <driver/gpio.h>
    10 #include <driver/gpio.h>
    11 
    11 
       
    12 #include <iot_button.h>
       
    13 
    12 #include <hap.h>
    14 #include <hap.h>
    13 
    15 
    14 #include <hap_apple_servs.h>
    16 #include <hap_apple_servs.h>
    15 #include <hap_apple_chars.h>
    17 #include <hap_apple_chars.h>
    16 
    18 
    21 
    23 
    22 #define DOOR_TASK_PRIORITY  1
    24 #define DOOR_TASK_PRIORITY  1
    23 #define DOOR_TASK_STACKSIZE 4 * 1024
    25 #define DOOR_TASK_STACKSIZE 4 * 1024
    24 #define DOOR_TASK_NAME      "hap_door"
    26 #define DOOR_TASK_NAME      "hap_door"
    25 
    27 
    26 #define DOOR_LOCK_GPIO_PIN GPIO_NUM_21
    28 #define RESET_NETWORK_BUTTON_TIMEOUT 3
    27 #define DOOR_BELL_GPIO_PIN GPIO_NUM_14
    29 
    28 #define DOOR_LOCK_GPIO_LOCKED 0
    30 #define DOOR_LOCK_GPIO_LOCKED 0
    29 #define DOOR_LOCK_GPIO_UNLOCKED 1
    31 #define DOOR_LOCK_GPIO_UNLOCKED 1
    30 
    32 
    31 #define HAP_LOCK_TARGET_STATE_UNSECURED 0
    33 #define HAP_LOCK_TARGET_STATE_UNSECURED 0
    32 #define HAP_LOCK_TARGET_STATE_SECURED 1
    34 #define HAP_LOCK_TARGET_STATE_SECURED 1
    33 
       
    34 static hap_val_t HAP_LOCK_CURRENT_STATE_UNSECURED = {.u = 0};
    35 static hap_val_t HAP_LOCK_CURRENT_STATE_UNSECURED = {.u = 0};
    35 static hap_val_t HAP_LOCK_CURRENT_STATE_SECURED = {.u = 1};
    36 static hap_val_t HAP_LOCK_CURRENT_STATE_SECURED = {.u = 1};
    36 
       
    37 static hap_val_t HAP_PROGRAMMABLE_SWITCH_EVENT_SINGLE_PRESS = {.u = 0};
    37 static hap_val_t HAP_PROGRAMMABLE_SWITCH_EVENT_SINGLE_PRESS = {.u = 0};
    38 
    38 
    39 #define ESP_INTR_FLAG_DEFAULT 0
    39 #define ESP_INTR_FLAG_DEFAULT 0
    40 
    40 
    41 static const uint8_t DOOR_EVENT_QUEUE_BELL = 1;
    41 static const uint8_t DOOR_EVENT_QUEUE_BELL = 1;
    42 static const uint8_t DOOR_EVENT_QUEUE_UNLOCK = 2;
    42 static const uint8_t DOOR_EVENT_QUEUE_UNLOCK = 2;
    43 static const uint8_t DOOR_EVENT_QUEUE_LOCK = 3;
    43 static const uint8_t DOOR_EVENT_QUEUE_LOCK = 3;
    44 static const uint8_t DOOR_EVENT_QUEUE_LOCK_TIMEOUT = 4;
    44 static const uint8_t DOOR_EVENT_QUEUE_LOCK_TIMEOUT = 4;
       
    45 
       
    46 static uint8_t tlv8buff[128];
       
    47 static hap_data_val_t null_tlv8 = { .buf = &tlv8buff, .buflen = 127 };
    45 
    48 
    46 static xQueueHandle door_event_queue = NULL;
    49 static xQueueHandle door_event_queue = NULL;
    47 static TimerHandle_t door_lock_timer = NULL;
    50 static TimerHandle_t door_lock_timer = NULL;
    48 
    51 
    49 /**
    52 /**
    85 
    88 
    86 	gpio_config(&io_conf);	 /* Set the GPIO configuration */
    89 	gpio_config(&io_conf);	 /* Set the GPIO configuration */
    87 }
    90 }
    88 
    91 
    89 /**
    92 /**
       
    93  * Enable a GPIO Pin for LED
       
    94  */
       
    95 static void led_init(uint32_t key_gpio_pin) {
       
    96 	gpio_config_t io_conf;
       
    97 
       
    98 	io_conf.intr_type		= GPIO_INTR_DISABLE;	 /* Interrupt for falling edge  */
       
    99 	io_conf.pin_bit_mask	= 1 << key_gpio_pin;	 /* Bit mask of the pins */
       
   100 	io_conf.mode			= GPIO_MODE_OUTPUT;	 /* Set as input mode */
       
   101 	io_conf.pull_up_en	= GPIO_PULLUP_DISABLE;	 /* Disable internal pull-up */
       
   102 	io_conf.pull_down_en	= GPIO_PULLDOWN_DISABLE;		 /* Disable internal pull-down */
       
   103 
       
   104 	gpio_config(&io_conf);	 /* Set the GPIO configuration */
       
   105 }
       
   106 
       
   107 static void reset_network_handler(void* arg) {
       
   108 	ESP_LOGI(TAG, "Resetting network");
       
   109 	hap_reset_network();
       
   110 }
       
   111 
       
   112 static void reset_init(uint32_t key_gpio_pin) {
       
   113 	button_handle_t handle = iot_button_create(key_gpio_pin, BUTTON_ACTIVE_LOW);
       
   114 	iot_button_add_on_release_cb(handle, RESET_NETWORK_BUTTON_TIMEOUT, reset_network_handler, NULL);
       
   115 }
       
   116 
       
   117 /**
    90  * Initialize the Door Hardware. Here, we just enebale the Door Bell detection.
   118  * Initialize the Door Hardware. Here, we just enebale the Door Bell detection.
    91  */
   119  */
    92 void door_hardware_init(gpio_num_t door_bell_gpio_num, gpio_num_t door_lock_gpio_num) {
   120 void door_hardware_init(gpio_num_t reset_gpio_num, gpio_num_t door_bell_gpio_num, gpio_num_t door_lock_gpio_num, gpio_num_t led_gpio_num) {
    93 	int queue_len = 4;
   121 	int queue_len = 4;
    94 	int queue_item_size = sizeof(uint8_t);
   122 	int queue_item_size = sizeof(uint8_t);
    95 
   123 
    96 	door_event_queue = xQueueCreate(queue_len, queue_item_size);
   124 	door_event_queue = xQueueCreate(queue_len, queue_item_size);
    97 	if (door_event_queue != NULL) {
   125 	if (door_event_queue != NULL) {
       
   126 		/* reset_init(reset_gpio_num); */
    98 		door_bell_init(door_bell_gpio_num);
   127 		door_bell_init(door_bell_gpio_num);
    99 		door_lock_init(door_lock_gpio_num);
   128 		door_lock_init(door_lock_gpio_num);
       
   129 		led_init(led_gpio_num);
       
   130 
   100 	}
   131 	}
   101 }
   132 }
   102 
   133 
   103 /* Mandatory identify routine for the accessory.
   134 /* Mandatory identify routine for the accessory.
   104  * In a real accessory, something like LED blink should be implemented
   135  * In a real accessory, something like LED blink should be implemented
   105  * got visual identification
   136  * got visual identification
   106  */
   137  */
   107 static int door_identify(hap_acc_t *ha) {
   138 static int door_identify(hap_acc_t *ha) {
   108 	ESP_LOGI(TAG, "Accessory identified");
   139 	ESP_LOGI(TAG, "Accessory identified");
       
   140 
       
   141 	for (int i = 0; i < 3; i++) {
       
   142 		gpio_set_level(CONFIG_HOMEKIT_DOOR_LED_GPIO_PIN, 1);
       
   143 		vTaskDelay(pdMS_TO_TICKS(500));
       
   144 		gpio_set_level(CONFIG_HOMEKIT_DOOR_LED_GPIO_PIN, 0);
       
   145 		vTaskDelay(pdMS_TO_TICKS(500));
       
   146 	}
       
   147 
   109 	return HAP_SUCCESS;
   148 	return HAP_SUCCESS;
   110 }
   149 }
   111 
   150 
   112 static void door_bell_ring(hap_char_t *door_bell_current_state) {
   151 static void door_bell_ring(hap_char_t *door_bell_current_state) {
   113 	ESP_LOGI(TAG, "Door bell ring event processed");
   152 	ESP_LOGI(TAG, "Door bell ring event processed");
   116 }
   155 }
   117 
   156 
   118 static void door_unlock(hap_char_t *door_lock_current_state) {
   157 static void door_unlock(hap_char_t *door_lock_current_state) {
   119 	ESP_LOGI(TAG, "Door unlock event processed");
   158 	ESP_LOGI(TAG, "Door unlock event processed");
   120 
   159 
   121 	gpio_set_level(DOOR_LOCK_GPIO_PIN, DOOR_LOCK_GPIO_UNLOCKED);
   160 	gpio_set_level(CONFIG_HOMEKIT_DOOR_LOCK_GPIO_PIN, DOOR_LOCK_GPIO_UNLOCKED);
   122 	hap_char_update_val(door_lock_current_state, &HAP_LOCK_CURRENT_STATE_UNSECURED);
   161 	hap_char_update_val(door_lock_current_state, &HAP_LOCK_CURRENT_STATE_UNSECURED);
   123 
   162 
   124 	xTimerReset(door_lock_timer, 10);
   163 	xTimerReset(door_lock_timer, 10);
   125 }
   164 }
   126 
   165 
   127 static void door_lock(hap_char_t *door_lock_current_state) {
   166 static void door_lock(hap_char_t *door_lock_current_state) {
   128 	ESP_LOGI(TAG, "Door lock event processed");
   167 	ESP_LOGI(TAG, "Door lock event processed");
   129 
   168 
   130 	gpio_set_level(DOOR_LOCK_GPIO_PIN, DOOR_LOCK_GPIO_LOCKED);
   169 	gpio_set_level(CONFIG_HOMEKIT_DOOR_LOCK_GPIO_PIN, DOOR_LOCK_GPIO_LOCKED);
   131 	hap_char_update_val(door_lock_current_state, &HAP_LOCK_CURRENT_STATE_SECURED);
   170 	hap_char_update_val(door_lock_current_state, &HAP_LOCK_CURRENT_STATE_SECURED);
   132 }
   171 }
   133 
   172 
   134 static void door_lock_timeout(hap_char_t *door_lock_target_state) {
   173 static void door_lock_timeout(hap_char_t *door_lock_target_state) {
   135 	ESP_LOGI(TAG, "Door lock timeout event processed");
   174 	ESP_LOGI(TAG, "Door lock timeout event processed");
   194 
   233 
   195 	/* Add a dummy Product Data */
   234 	/* Add a dummy Product Data */
   196 	uint8_t product_data[] = {'E','S','P','3','2','H','A','P'};
   235 	uint8_t product_data[] = {'E','S','P','3','2','H','A','P'};
   197 	hap_acc_add_product_data(door_accessory, product_data, sizeof(product_data));
   236 	hap_acc_add_product_data(door_accessory, product_data, sizeof(product_data));
   198 
   237 
   199 	hap_serv_t *door_bell_service = hap_serv_stateless_programmable_switch_create(0);
   238 	hap_serv_t *door_bell_service = hap_serv_doorbell_create(0);
   200 	hap_serv_add_char(door_bell_service, hap_char_name_create("Doorbell"));
   239 	hap_serv_add_char(door_bell_service, hap_char_name_create("Doorbell"));
   201 	hap_char_t *door_bell_current_state = hap_serv_get_char_by_uuid(door_bell_service, HAP_CHAR_UUID_PROGRAMMABLE_SWITCH_EVENT);
   240 	hap_char_t *door_bell_current_state = hap_serv_get_char_by_uuid(door_bell_service, HAP_CHAR_UUID_PROGRAMMABLE_SWITCH_EVENT);
   202 
   241 
   203 	hap_serv_t *door_lock_service = hap_serv_lock_mechanism_create(HAP_LOCK_CURRENT_STATE_SECURED.u, HAP_LOCK_TARGET_STATE_SECURED);
   242 	hap_serv_t *door_lock_service = hap_serv_lock_mechanism_create(HAP_LOCK_CURRENT_STATE_SECURED.u, HAP_LOCK_TARGET_STATE_SECURED);
   204 	hap_serv_add_char(door_lock_service, hap_char_name_create("Door Lock"));
   243 	hap_serv_add_char(door_lock_service, hap_char_name_create("Door Lock"));
   211 	hap_acc_add_serv(door_accessory, door_bell_service);
   250 	hap_acc_add_serv(door_accessory, door_bell_service);
   212 	hap_acc_add_serv(door_accessory, door_lock_service);
   251 	hap_acc_add_serv(door_accessory, door_lock_service);
   213 
   252 
   214 	hap_add_accessory(door_accessory);	 /* Add the Accessory to the HomeKit Database */
   253 	hap_add_accessory(door_accessory);	 /* Add the Accessory to the HomeKit Database */
   215 
   254 
   216 	door_hardware_init(DOOR_BELL_GPIO_PIN, DOOR_LOCK_GPIO_PIN);	 /* Initialize the appliance specific hardware. This enables out-in-use detection */
   255 	/* Initialize the appliance specific hardware. This enables out-in-use detection */
       
   256 	door_hardware_init(CONFIG_HOMEKIT_DOOR_WIFI_RESET_GPIO_PIN, CONFIG_HOMEKIT_DOOR_BELL_GPIO_PIN, CONFIG_HOMEKIT_DOOR_LOCK_GPIO_PIN, CONFIG_HOMEKIT_DOOR_LED_GPIO_PIN);
   217 
   257 
   218 	/* For production accessories, the setup code shouldn't be programmed on to
   258 	/* For production accessories, the setup code shouldn't be programmed on to
   219 	 * the device. Instead, the setup info, derived from the setup code must
   259 	 * the device. Instead, the setup info, derived from the setup code must
   220 	 * be used. Use the factory_nvs_gen utility to generate this data and then
   260 	 * be used. Use the factory_nvs_gen utility to generate this data and then
   221 	 * flash it into the factory NVS partition.
   261 	 * flash it into the factory NVS partition.