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. |