Advertisement
Guest User

lock

a guest
Mar 19th, 2019
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.37 KB | None | 0 0
  1. *
  2.  * Implemenetation of lock mechanism accessory for a magnet lock.
  3.  * When unlocked, it changes relay state (unlocks) for configured period and then
  4.  * changes it back.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <espressif/esp_wifi.h>
  9. #include <espressif/esp_sta.h>
  10. #include <espressif/esp_common.h>
  11. #include <esp/uart.h>
  12. #include <esp8266.h>
  13. #include <FreeRTOS.h>
  14. #include <task.h>
  15. #include <etstimer.h>
  16. #include <esplibs/libmain.h>
  17.  
  18. #include <homekit/homekit.h>
  19. #include <homekit/characteristics.h>
  20. #include <wifi_config.h>
  21.  
  22. #include "button.h"
  23.  
  24. // The GPIO pin that is connected to a relay
  25. const int relay_gpio = 12;
  26.  
  27. const int relay2_gpio = 13;
  28. // The GPIO pin that is connected to a LED
  29. // const int led_gpio = 13;
  30. const int led_gpio = 2;
  31. // The GPIO pin that is connected to a button
  32. // const int button_gpio = 0;
  33. const int button_gpio = 4;
  34.  
  35. // Timeout in seconds to open lock for
  36. const int unlock_period = 5;  // 5 seconds
  37. // Which signal to send to relay to open the lock (0 or 1)
  38. const int relay_open_signal = 1;
  39.  
  40. void lock_lock();
  41. void lock_unlock();
  42.  
  43. void relay_write(int value) {
  44.     gpio_write(relay_gpio, value ? 1 : 0);
  45.     gpio_write(relay2_gpio, value ? 1 : 0);
  46. }
  47.  
  48. void led_write(bool on) {
  49.     gpio_write(led_gpio, on ? 0 : 1);
  50. }
  51.  
  52. void reset_configuration_task() {
  53.     //Flash the LED first before we start the reset
  54.     for (int i=0; i<3; i++) {
  55.         led_write(true);
  56.         vTaskDelay(100 / portTICK_PERIOD_MS);
  57.         led_write(false);
  58.         vTaskDelay(100 / portTICK_PERIOD_MS);
  59.     }
  60.  
  61.     printf("Resetting Wifi Config\n");
  62.  
  63.     wifi_config_reset();
  64.  
  65.     vTaskDelay(1000 / portTICK_PERIOD_MS);
  66.  
  67.     printf("Resetting HomeKit Config\n");
  68.  
  69.     homekit_server_reset();
  70.  
  71.     vTaskDelay(1000 / portTICK_PERIOD_MS);
  72.  
  73.     printf("Restarting\n");
  74.  
  75.     sdk_system_restart();
  76.  
  77.     vTaskDelete(NULL);
  78. }
  79.  
  80. void reset_configuration() {
  81.     printf("Resetting configuration\n");
  82.     xTaskCreate(reset_configuration_task, "Reset configuration", 256, NULL, 2, NULL);
  83. }
  84.  
  85. void gpio_init() {
  86.     gpio_enable(led_gpio, GPIO_OUTPUT);
  87.  
  88.     led_write(false);
  89.  
  90.     gpio_enable(relay_gpio, GPIO_OUTPUT);
  91.  
  92.     gpio_enable(relay2_gpio, GPIO_OUTPUT);
  93.  
  94.     relay_write(!relay_open_signal);
  95. }
  96.  
  97. void button_callback(uint8_t gpio, button_event_t event) {
  98.     switch (event) {
  99.         case button_event_single_press:
  100.             printf("Toggling relay\n");
  101.             lock_unlock();
  102.             break;
  103.         case button_event_long_press:
  104.             reset_configuration();
  105.             break;
  106.         default:
  107.             printf("Unknown button event: %d\n", event);
  108.     }
  109. }
  110.  
  111. void lock_identify_task(void *_args) {
  112.     // We identify the Sonoff by Flashing it's LED.
  113.     for (int i=0; i<3; i++) {
  114.         for (int j=0; j<2; j++) {
  115.             led_write(true);
  116.             vTaskDelay(100 / portTICK_PERIOD_MS);
  117.             led_write(false);
  118.             vTaskDelay(100 / portTICK_PERIOD_MS);
  119.         }
  120.  
  121.         vTaskDelay(250 / portTICK_PERIOD_MS);
  122.     }
  123.  
  124.     led_write(false);
  125.  
  126.     vTaskDelete(NULL);
  127. }
  128.  
  129. void lock_identify(homekit_value_t _value) {
  130.     printf("Lock identify\n");
  131.     xTaskCreate(lock_identify_task, "Lock identify", 128, NULL, 2, NULL);
  132. }
  133.  
  134.  
  135. typedef enum {
  136.     lock_state_unsecured = 0,
  137.     lock_state_secured = 1,
  138.     lock_state_jammed = 2,
  139.     lock_state_unknown = 3,
  140. } lock_state_t;
  141.  
  142.  
  143.  
  144. homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, "Lock");
  145.  
  146. homekit_characteristic_t lock_current_state = HOMEKIT_CHARACTERISTIC_(
  147.     LOCK_CURRENT_STATE,
  148.     lock_state_unknown,
  149. );
  150.  
  151. void lock_target_state_setter(homekit_value_t value);
  152.  
  153. homekit_characteristic_t lock_target_state = HOMEKIT_CHARACTERISTIC_(
  154.     LOCK_TARGET_STATE,
  155.     lock_state_secured,
  156.     .setter=lock_target_state_setter,
  157. );
  158.  
  159. void lock_target_state_setter(homekit_value_t value) {
  160.     lock_target_state.value = value;
  161.  
  162.     if (value.int_value == 0) {
  163.         lock_unlock();
  164.     } else {
  165.         lock_lock();
  166.     }
  167. }
  168.  
  169. void lock_control_point(homekit_value_t value) {
  170.     // Nothing to do here
  171. }
  172.  
  173.  
  174. ETSTimer lock_timer;
  175.  
  176. void lock_lock() {
  177.     sdk_os_timer_disarm(&lock_timer);
  178.  
  179.     relay_write(!relay_open_signal);
  180.     led_write(false);
  181.  
  182.     if (lock_current_state.value.int_value != lock_state_secured) {
  183.         lock_current_state.value = HOMEKIT_UINT8(lock_state_secured);
  184.         homekit_characteristic_notify(&lock_current_state, lock_current_state.value);
  185.     }
  186. }
  187.  
  188. void lock_timeout() {
  189.     if (lock_target_state.value.int_value != lock_state_secured) {
  190.         lock_target_state.value = HOMEKIT_UINT8(lock_state_secured);
  191.         homekit_characteristic_notify(&lock_target_state, lock_target_state.value);
  192.     }
  193.  
  194.     lock_lock();
  195. }
  196.  
  197. void lock_init() {
  198.     lock_current_state.value = HOMEKIT_UINT8(lock_state_secured);
  199.     homekit_characteristic_notify(&lock_current_state, lock_current_state.value);
  200.  
  201.     sdk_os_timer_disarm(&lock_timer);
  202.     sdk_os_timer_setfn(&lock_timer, lock_timeout, NULL);
  203. }
  204.  
  205. void lock_unlock() {
  206.     relay_write(relay_open_signal);
  207.     led_write(true);
  208.  
  209.     lock_current_state.value = HOMEKIT_UINT8(lock_state_unsecured);
  210.     homekit_characteristic_notify(&lock_current_state, lock_current_state.value);
  211.  
  212.     if (unlock_period) {
  213.         sdk_os_timer_disarm(&lock_timer);
  214.         sdk_os_timer_arm(&lock_timer, unlock_period * 1000, 0);
  215.     }
  216. }
  217.  
  218. homekit_accessory_t *accessories[] = {
  219.     HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_door_lock, .services=(homekit_service_t*[]){
  220.         HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){
  221.             &name,
  222.             HOMEKIT_CHARACTERISTIC(MANUFACTURER, "HaPK"),
  223.             HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1"),
  224.             HOMEKIT_CHARACTERISTIC(MODEL, "Basic"),
  225.             HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"),
  226.             HOMEKIT_CHARACTERISTIC(IDENTIFY, lock_identify),
  227.             NULL
  228.         }),
  229.         HOMEKIT_SERVICE(LOCK_MECHANISM, .primary=true, .characteristics=(homekit_characteristic_t*[]){
  230.             HOMEKIT_CHARACTERISTIC(NAME, "Lock"),
  231.             &lock_current_state,
  232.             &lock_target_state,
  233.             NULL
  234.         }),
  235.         HOMEKIT_SERVICE(LOCK_MANAGEMENT, .characteristics=(homekit_characteristic_t*[]){
  236.             HOMEKIT_CHARACTERISTIC(LOCK_CONTROL_POINT,
  237.                 .setter=lock_control_point
  238.             ),
  239.             HOMEKIT_CHARACTERISTIC(VERSION, "1"),
  240.             NULL
  241.         }),
  242.         NULL
  243.     }),
  244.     NULL
  245. };
  246.  
  247. homekit_server_config_t config = {
  248.     .accessories = accessories,
  249.     .password = "111-11-111"
  250. };
  251.  
  252. void on_wifi_ready() {
  253.     homekit_server_init(&config);
  254. }
  255.  
  256. void create_accessory_name() {
  257.     uint8_t macaddr[6];
  258.     sdk_wifi_get_macaddr(STATION_IF, macaddr);
  259.  
  260.     int name_len = snprintf(NULL, 0, "Lock-%02X%02X%02X",
  261.                             macaddr[3], macaddr[4], macaddr[5]);
  262.     char *name_value = malloc(name_len+1);
  263.     snprintf(name_value, name_len+1, "Lock-%02X%02X%02X",
  264.              macaddr[3], macaddr[4], macaddr[5]);
  265.  
  266.     name.value = HOMEKIT_STRING(name_value);
  267. }
  268.  
  269. void user_init(void) {
  270.     uart_set_baud(0, 115200);
  271.  
  272.     create_accessory_name();
  273.  
  274.     wifi_config_init("lock", NULL, on_wifi_ready);
  275.     gpio_init();
  276.     lock_init();
  277.  
  278.     if (button_create(button_gpio, 0, 4000, button_callback)) {
  279.         printf("Failed to initialize button\n");
  280.     }
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement