Умный дом iOS разработчика +8


В свободное время (а иногда и в рабочее) я изучаю микроконтроллеры и собираю умный дом у себя в квартире, а так как по профессии я iOS-разработчик, то на умный дом я смотрю через призму iPhone и HomeKit. После сборки более-менее рабочего умного дома и, столкнувшись с кучей проблем, решил рассказать про свой опыт и устройства в цикле из 2 статей. Первая статья будет небольшим ликбезом в теорию микроконтроллеров и протоколов, а во второй уже поделюсь конкретным применением этих протоколов и фреймворков в моем умном доме.

Введение

Есть 3 основных пути, как собрать умный дом у себя в квартире

  1. Построить все на готовой экосистеме от какого-либо производителя (Samsung SmartThings, LG ThinQ...)

  2. Собрать умный дом на готовом фреймворке (HomeAssistant,  HomeBridge, Apple HomeKit)

  3. Скомбинировать первые два подхода.

В первом варианте умные устройства уже готовые с готовым приложением, можно не париться с прошивкой микроконтроллеров, но зачастую устройства из разных экосистем не совместимы между собой. Второй подход уже более гибкий и можно подключить устройства от разных производителей в одну экосистему, а также сделать свое умное устройство из не очень умного. Из минусов такого подхода можно отметить сложность первой настройки, а также зоопарк протоколов которые нужно поддержать (ZigBee, ZWave, Thread, WiFi, Bluetooth…). В этой статье как раз поговорим про второй подход и как можно докрутить «умную» часть «тупым» девайсам. 

Например, у нас есть светодиодная лента, в которой нет вайфай модуля, и единственный способ ее отключить – это физический выключатель электричества. В такой ситуации можно либо купить умную светодиодную ленту и заменить старую, но такие светодиодные ленты стоят несколько тысяч рублей. А можно всего лишь за 200 рублей докупить микроконтроллер с WiFi, и светодиодная лента будет управляться с телефона. Звучит просто, но встает вопрос какой микроконтроллер выбрать, как написать прошивку для него и как связать микроконтроллер с телефоном.

Микроконтроллеры

Большинство «железячников» начинает свой путь с Arduino. Она отлично подходит для прототипирования, поэтому можно обойтись без пайки, и имеет собственный фреймворк, так что не приходится писать на чистом C. Но, к сожалению, плата довольно большая, не имеет встроенного WiFi и Bluetooth, да и оригинальная плата стоит несколько тысяч рублей.  Для Bluetooth и WiFi приходится докупать отдельные модули, такие как ESP8266.

ESP12F на базе ESP8266
ESP12F на базе ESP8266

ESP32

В один момент кто-то осознал, что WiFi модуль будет помощнее самой Arduino и спокойно может выступать самостоятельным микроконтроллером со своей прошивкой, а стоит в разы дешевле, после чего модуль стали использовать не совсем по назначению. Но  Espressif (компания производитель ESP8266) вовремя опомнилась и, поняв что ее модуль использует не так как планировалось, выпустила более подходящий микроконтроллер на замену Arduino и ESP8266 – ESP32, который можно купить на алиэкспресс рублей за 200 и использовать в своих домашних проектах умного дома.

Другие микроконтроллеры

SwiftIO
SwiftIO

Несмотря на дешевизну и простоту ESP32, есть и другие интересные варианты. Например, микроконтроллер на Swift’е. Будучи iOS-разработчиком я не мог пройти мимо и не заказать эту плату :)
Для вышеописанных кейсов можно использовать и всем известную Raspberry Pi. Но она стоит слишком дорого, чтобы проводить на ней эксперименты. У нее также есть GPIO, которыми можно управлять через питон, но у нее стоит слабенький трансформатор напряжения, и если подать слишком большое напряжение, она просто сгорит, что и произошло с моей первой Raspberry Pi 4, поэтому ее лучше использовать только как домашний сервер, но об этом в следующей статье.

Фреймворки для ESP32

Для ESP32 также есть Arduino фреймворк, то есть для нее можно писать такой же код как и для Arduino в Arduino IDE, с некоторыми адаптациями функций. Пример кода:

#define LED 2

void setup() {
  // Set pin mode
  pinMode(LED,OUTPUT);
}

void loop() {
  delay(500);
  digitalWrite(LED,HIGH);
  delay(500);
  digitalWrite(LED,LOW);
}

Если хочется больше хардкора, у Espressif есть собственный фрейморк на C - ESP-IDF на базе FreeRTOS. Пример кода:

static void blink_led(void)
{
    /* Set the GPIO level according to the state (LOW or HIGH)*/
    gpio_set_level(BLINK_GPIO, s_led_state);
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
    gpio_reset_pin(BLINK_GPIO);
    /* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}

#endif

void app_main(void)
{

    /* Configure the peripheral according to the LED type */
    configure_led();

    while (1) {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
        blink_led();
        /* Toggle the LED state */
        s_led_state = !s_led_state;
        vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
    }
}

Базовый флоу умного дома

С микроконтроллером определились, теперь надо понять, как написать прошивку для него и связать с телефоном.

Базовый флоу
Базовый флоу
  1. Изначально передаем пароль от домашнего WiFi на микроконтроллер (это называется WiFi provisioning), чтобы подключить его к нашей локальной сети, либо же просто зашиваем пароль в коде, но тогда при смене пароля придется перепрошивать микроконтроллер.

  2. Разворачиваем локальный сервер на микроконтроллере и обращаемся к нему по http, как к обычному серверу, либо же подключаемся к нему по MQTT. 

Как передать пароль от WiFI

Есть 3 основных способа:

  • Bluetooth

  • WiFi

  • Специальные протоколы

Bluetooth

Про подробности Bluetooth можно отдельную статью написать, но сейчас на этом останавливаться не будем. Скажу только, что нужно подключиться по BLE к мироконтроллеру на телефоне и отправить пароль в приложении через CoreBluetooth. Подробнее можно посмотреть в примерах от Espressif.  У них также есть приложения для iOS и Androind с открытым исходным кодом для wifi provisioning.

WiFi

WiFi может работать в 2 режимах (wifi direct и его аналоги в расчет не берем): AP и STA. AP – это когда ESP32 выпускает точкой доступа, как будто это wifi роутер, к которому можно подключиться. STA – это когда ESP32 сама подключается к роутеру. 

Соответственно, нужно перевести микроконтроллер в режим AP, подключиться к ней с телефона, отправить пароль от WiFi и затем перевести в режим STA и подключиться к домашнему WiFi. У Espressif также есть для этого примеры и приложения.

Специальные протоколы

Помимо стандартных Bluetooth и WiFi есть специальные протоколы для передачи пароля, такие как SmartConfig и EasyConnect

Как подключиться к микроконтроллеру

Локальный сервер

Наиболее простой способ это развернуть на микроконтроллере сервер и обращаться к нему по HTTP. Для примера код, который я использую в светодиодной ленте.

MQTT

Есть специальный протокол для умного дома, это что-то вроде сокетов, но я с ним напрямую поработать особо не успел. Знаю только, что он используется в Яндекс.Станции. 

HomeKit

Если вы, как и я, «продали душу» эплу и сидите на его экосистеме, проще сделать свое умное устройство на базе HomeKit. HomeKit – это такой же протокол общения между устройствами. Apple не так давно заопенсорсила свою либу для хоббистов. А Espressif адаптировал ее под свои платы. Если разрабатывать Enterprise решение (купить MFi подписку), то не надо даже вручную провижинить пароль от вайфая. 

Все сводится к тому, чтобы взять готовый пример от Espressif для HomeKit адаптировать под свои нужды, то есть добавить функции которые будут физически включать/выключать вентилятор, например, и залить на ESP32. Обработка статусов от HomeKit для вентилятора из примеров Espressif:

static int fan_write(hap_write_data_t write_data[], int count,
        void *serv_priv, void *write_priv)
{
    if (hap_req_get_ctrl_id(write_priv)) {
        ESP_LOGI(TAG, "Received write from %s", hap_req_get_ctrl_id(write_priv));
    }
    ESP_LOGI(TAG, "Fan Write called with %d chars", count);
    int i, ret = HAP_SUCCESS;
    hap_write_data_t *write;
    for (i = 0; i < count; i++) {
        write = &write_data[i];
        if (!strcmp(hap_char_get_type_uuid(write->hc), HAP_CHAR_UUID_ON)) {
            ESP_LOGI(TAG, "Received Write. Fan %s", write->val.b ? "On" : "Off");
            /* TODO: Control Actual Hardware */
            hap_char_update_val(write->hc, &(write->val));
            *(write->status) = HAP_STATUS_SUCCESS;
        } else if (!strcmp(hap_char_get_type_uuid(write->hc), HAP_CHAR_UUID_ROTATION_DIRECTION)) {
            if (write->val.i > 1) {
                *(write->status) = HAP_STATUS_VAL_INVALID;
                ret = HAP_FAIL;
            } else {
                ESP_LOGI(TAG, "Received Write. Fan %s", write->val.i ? "AntiClockwise" : "Clockwise");
                hap_char_update_val(write->hc, &(write->val));
                *(write->status) = HAP_STATUS_SUCCESS;
            }
        } else {
            *(write->status) = HAP_STATUS_RES_ABSENT;
        }
    }
    return ret;
}

Matter

Бывший Zigbee альянс переименовался и разработал новый стандарт на базе WiFi, Bluetooth и Thread (забавно что без Zigbee). В него входят все крупные игроки: Google, Amazon, Apple. И Apple уже добавила поддержку Matter в HomeKit – устройства на базе Matter теперь будут добавлятьcя так же как и нативно поддерживающие HomeKit. А Espressif уже сделал пару примеров с поддержкой Matter для некоторых версий ESP32.

ESPHome

Чтобы не писать прошивку самому есть так же готовые решения вроде ESPHome. 

Микроконтроллер и остальные платы

Все эти манипуляции с подключением к ESP32 нужны были, чтобы можно было физически управлять модулями, к которым подключена ESP32. Для это в ней есть набор GPIO.

Распиновка ESP32
Распиновка ESP32

Мы можем подавать напряжения на GPIO, тем самым включая или выключая электричество на подсоединенные плата. С помощью широтно-импульсной модуляции так же можно моделировать управление яркость например, если к микроконтроллеру подключен светодиод. Некоторые пины (см. картинку) также поддерживают более сложные протоколы как UART, I2C и SPI. UART используется, например, для GPS модулей, а I2C и SPI для экранов. В рамках статьи останавливаться на этом не будем. Могу посоветовать хороший курс по ESP32.

Заключение

Это было небольшое теоретическое вступление, которое пришлось изучить, чтобы собрать свой умный дом. Но об этом уже в следующей статье.




К сожалению, не доступен сервер mySQL