Привет всем!

В своем «умном доме» я решил, что все устройства должны быть завязаны на локальном сервере, чтобы без интернета он не превратился в тыкву.

Но почти всё так или иначе привязано к облаку. Этот пост о том, как отвязать устройства Sonoff от облаков.

Да, я знаю, что таких постов очень много и уже все рассказали, как прошить Sonoff. Но я хочу показать как можно отвязать от облака Sonoff DW2, не прошивая его. Прошить его в любом случае не получится, ведь там не ESP8266, а другая микросхема.

Что понадобится для освобождения от облаков:
  • Sonoff Basic, Sonoff 4CH — понадобится паяльник и USB-TTL преобразователь;
  • Sonoff DW2 — собственный сервер.

В посте я использую ESPHome + Home Assistant + Docker + PHP, вы можете использовать любое другое ПО, тут главное принцип работы.

Начнем с простого.

Sonoff Basic R2




Хорошая игрушка для умного дома, если вам требуется поуправлять отдельным светильником и не хочется менять всю проводку

Первым делом подготавливаем конфиг нужной нам прошивки (актуальная версия находится тут):
Конфиг ESPHome
Copy
# Basic Config
esphome:
  name: sonoff_basic_r2
  platform: ESP8266
  board: esp8285

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
api:
ota:

# Device Specific Config
binary_sensor:
  - platform: gpio
    id: push_button
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    internal: true
    on_press:
      # Prevents unintended LED lit states.
      if:
        condition:
          - switch.is_off: relay
        then:
          - switch.turn_on: blue_led
          - switch.turn_on: relay
        else:
          - switch.turn_off: relay

switch:
  # The relay switches on the red side of the LED when active.
  - platform: gpio
    name: "Sonoff Basic Relay"
    pin: GPIO12
    id: relay
    on_turn_off:
      if:
        condition:
          - switch.is_on: blue_led
        then:
          - switch.turn_off: blue_led
  # With this we can control the blue side of the LED.
  - platform: gpio
    id: blue_led
    pin:
      number: GPIO13
      inverted: True



Теперь переходим к железу.

Для удобства припаиваем гребенку с шагом 2.54 на плату и подключаемся USB-TTL преобразователем, например CH340G, соблюдая пины:
  • GND — GND
  • TX — TX (возможно RX, зависит от преобразователя)
  • RX — RX (возможно TX, зависит от преобразователя)
  • 3.3V — 3.3V

Перед подключением Sonoff к ПК зажмите кнопку на плате, это необходимо для перехода в режим прошивки. Бывает такое, что устройство не определяется, поэтому я рекомендую поменять местами TX и RX пины, возможно, ваш программатор не учитывает такие моменты.



Сама инструкция по прошивке, скорее всего, вам уже известна, но для тех, кто делает это впервые, рекомендую ознакомиться с сайтом esphome.io

На этом наша работа с R2 окончена, теперь это ESPHome Sonoff R2.

Переходим к следующему пациенту.

Sonoff 4CH (Pro)



Цифра 5 означает, что это пятый контроллер в моем доме.

Приставка PRO означает, что вам доступны 433 МГц выключатели, но сама микросхема, отвечающая за 433 МГц протокол, распаяна отдельно, и ей управлять не получится, но после прошивки она продолжает работать как раньше.

По моим ощущениям 433 МГц протокол стал работать даже быстрее, чем до прошивки, но это может быть плацебо.

Отлично подходит для управления светом в комнатах. Я использую 3 таких на управлении светом во всем доме и 1 для управления насосами котла отопления.

Принцип прошивки аналогичен Basic R2, отличается лишь конфиг (актуальная версия находится тут):
Конфиг ESPHome
Copy
# Basic Config
esphome:
  name: sonoff_4chpror2
  platform: ESP8266
  board: esp01_1m

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
api:
ota:

# Device Specific Config
binary_sensor:
  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: "relay_1"
  - platform: gpio
    pin:
      number: GPIO9
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: "relay_2"
  - platform: gpio
    pin:
      number: GPIO10
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: "relay_3"
  - platform: gpio
    pin:
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: "relay_4"

  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    name: "Sonoff 4CH Pro Button 1"
  - platform: gpio
    pin:
      number: GPIO9
      mode: INPUT_PULLUP
      inverted: True
    name: "Sonoff 4CH Pro Button 2"
  - platform: gpio
    pin:
      number: GPIO10
      mode: INPUT_PULLUP
      inverted: True
    name: "Sonoff 4CH Pro Button 3"
  - platform: gpio
    pin:
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: True
    name: "Sonoff 4CH Pro Button 4"

  - platform: status
    name: "Sonoff 4CH Pro Status"

switch:
  - platform: gpio
    name: "Relay 1"
    pin: GPIO12
    id: "relay_1"
  - platform: gpio
    name: "Relay 2"
    pin: GPIO5
    id: "relay_2"
  - platform: gpio
    name: "Relay 3"
    pin: GPIO4
    id: "relay_3"
  - platform: gpio
    name: "Relay 4"
    pin: GPIO15
    id: "relay_4"


Заливаем прошивку и радуемся отвязанному ESPHome Sonoff 4CH (Pro) Max Super Digital.

Настало время самого сложного для меня пациента.

Sonoff DW2




Это единственное устройство у которого был доступ в интернет до сегодняшнего дня, у всех остальных «умных устройств» интернет отключен для безопасности.

В интернете я не нашел, как локально работать с датчиком двери, поэтому пришлось разбираться самому.

Начнем с принципа работы: DW2 подключается к вашей Wi-Fi сети и ждет прерывания от «открытия» или «закрытия» двери, в этот момент отправляется запрос на сервер eu-api.coolkit.cc, а уже с него вы получаете всю информацию.

Довольно сложная схема для простого датчика, подумал я и полез в Wireshark. Подменив DNS запись для домена eu-api.coolkit.cc на свой IP, я заметил обращение на 8080 порт, ура, они используют HTTP — значит, это победа! Нет, они используют HTTPS

Запустив nginx на своем сервере, я обнаружил странные логи такого вида:
Логи nginx
192.168.65.1 - - [29/Oct/2023:16:36:50 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03i\xB5\x19G\xB1\xB2X}\xA3L\xCF\x99\x11\x84 \x00\xCE\x88\xB2S\xBC\xFC$\x86bp\xDA\xFA*\xEFl\xC8 \xB5\x12t\xDC\x13\x80W\x8E\xB1\xD5*\x00\x9E\xAF\xABzz\xEFpx\x92\xFCmY0\x03\xB6a\xE9\xF1\xC5\xC5\x00*" 400 157 "-" "-" "-"

192.168.65.1 - - [29/Oct/2023:16:36:53 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\x0B;'hR\x90\xAAY\x06Z\x82c6\xEC\x02p1\xF0\xEFF\xF5\xF3j\x99\x08r\xC1\xA2\x0E\xB6n\xD4 \xE5\x90\x1E\xA7N\xDC\xF3\xCA\xEA\x8C\x8Af5\xC4k\x95\x80W\x8A{\x90\x83\xCB\xBDxR\xB5\xF7\xFC\xFF<\x85\x00,\x8A\x8A\x13\x01\x13\x02\x13\x03\xC0,\xC0+\xCC\xA9\xC00\xC0/\xCC\xA8\xC0" 400 157 "-" "-" "-"

192.168.65.1 - - [29/Oct/2023:16:36:53 +0000] "\x16\x03\x01\x00\x97\x01\x00\x00\x93\x03\x01y|q\x17\x1B\xDD\xDB\xC3\xD79\x22\x1C\xA6nf\x0B]\xAC)^5\xFA5p\xF0\x8DS\x93\xF3\xED\x8AJ\x00\x00\x14\xC0" 400 157 "-" "-" "-"



Интересно, но ничего не понятно.

А что если это HTTPS, ведь первые байты у всех запросов одинаковые?

Да, это HTTPS, но на 8080 порту, странно, но ладно.

Конечно, я расстроился, ожидая SSL Pinning или шифрования данных внутри запроса, но нет, никакого шифрования нет и сертификат Sonoff DW2 не проверяет.

Берем любой сертификат, подсовываем его в nginx и запускаем php-fpm для удобства разработки.

И вот мы получаем успешный POST запрос:

Лог nginx
192.168.65.1 - - [29/Oct/2023:19:39:55 +0000] "POST /api/user/device/update  HTTP/1.1" 200 5 "-" "-" "-"

Array
(
    [deviceid] => **********
    [d_seq] => 1546272314
    [params] => Array
        (
            [switch] => off
            [battery] => 2.202
            [fwVersion] => 1000.2.925
            [type] => 3
            [chipID] => **********
            [mac] => **********
            [rssi] => -83
        )

)



Отлично, мы получили информацию с датчика. Пишем скрипт-обработчик и добавляем перенаправление DNS запроса на свой сервер. Я использую Adguard Home, тут есть пункт «Перезапись DNS-запросов», в нем добавляем домен eu-api.coolkit.cc с вашим IP. Не забудьте в DHCP указать первым DNS свой Adguard Home.

Далее добавляем в конфиг следующие строки Home Assistant, чтобы появились новые объекты:

configuration.yaml
sensor:
  - platform: template
    sensors:
      entry_door_battery_voltage:
        unique_id: 5bc4eb632179f65962327215e2acf9e18d5a83f1
        device_class: voltage
        unit_of_measurement: 'V'
        value_template: ''
      entry_door_rssi:
        unique_id: 053082ee1f19d9ca6a58a0cdb9061ffd87de2fc4
        device_class: signal_strength
        unit_of_measurement: 'dBm'
        value_template: ''

binary_sensor:
  - platform: template
    sensors:
      entry_door:
        unique_id: 130e755dcb5dfa0696f0835fb73f1307c00e6c76
        device_class: door
        value_template: ''



и получаем долгосрочный токен в HA, его можно выпустить в самом низу страницы /profile

Для удобства и быстрого старта я использую Docker.

Конфигурация nginx
upstream php-sonoff-handler {
    server php:9000;
}

 server {
        listen 8080 ssl;
        server_name  eu-api.coolkit.cc;

        ssl_certificate /etc/nginx/ssl/servercert.pem;
        ssl_certificate_key /etc/nginx/ssl/serverkey.pem;

        ssl_dhparam /etc/nginx/ssl/dhparams.pem;

        location / {
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/project/sonoff.php;

            fastcgi_pass php-sonoff-handler;

            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;

            fastcgi_max_temp_file_size 0;
        }
}


Конфигурация Docker Compose
version: '3'

services:
  php:
    container_name: php
    image: "php:8.2-fpm"
    volumes:
      - ./php:/usr/share/nginx/html/project
    restart: unless-stopped
  nginx:
    container_name: nginx
    image: "nginx:latest"
    volumes:
      - ./nginx:/etc/nginx:ro
    restart: unless-stopped
    ports:
      - "8080:8080"



Добавляем скрипт в /php/sonoff.php.

Скрипт позволяет добавлять несколько датчиков, достаточно указать каждому свой ID.

Вместо ******* укажите deviceid своего устройства. Его можно узнать в приложении ewelink, пункт «ID устройства».

PHP скрипт
<?php
const HA_API_URL = "http://homeassistant:8123/api/states/";
const HA_TOKEN = 'ВАШ ТОКЕН';

$listDevices = [
    '**********' => [
        'id'     => 'entry_door',
        'name'   => 'Входная дверь',
        'v_name' => 'Входная дверь (Напряжение)',
        's_name' => 'Входная дверь (Сигнал)',
    ],
];

$data = json_decode(file_get_contents('php://input'), true);

$currentDevice = $listDevices[$data['deviceid']];

sendData(sprintf('binary_sensor.%s', $currentDevice['id']), [
    'state'      => $data['params']['switch'],
    'attributes' => [
        'friendly_name' => $currentDevice['name'],
        'device_class'  => 'door',
    ],
]);

sendData(sprintf('sensor.%s_battery_voltage', $currentDevice['id']), [
    'state'      => $data['params']['battery'],
    'attributes' => [
        'friendly_name'       => $currentDevice['v_name'],
        'state_class'         => 'measurement',
        'unit_of_measurement' => 'V',
        'device_class'        => 'voltage',
    ],
]);

sendData(sprintf('sensor.%s_rssi', $currentDevice['id']), [
    'state'      => $data['params']['rssi'],
    'attributes' => [
        'friendly_name'       => $currentDevice['s_name'],
        'state_class'         => 'measurement',
        'unit_of_measurement' => 'dBm',
        'device_class'        => 'signal_strength',
    ],
]);


function sendData($sensor, $postData)
{
    $url = HA_API_URL . $sensor;

    // for sending data as json type
    $fields = json_encode($postData);

    $ch = curl_init($url);
    curl_setopt(
        $ch,
        CURLOPT_HTTPHEADER,
        [
            'Content-Type: application/json', // if the content type is json
            'Authorization: Bearer ' . HA_TOKEN, // if you need token in header
        ]
    );
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

    $result = curl_exec($ch);
    curl_close($ch);
}



Запускаем docker и проверяем датчик в панели HA, информация отправляется только при открытии/закрытии двери.

Для удобства я создал репозиторий с примерами кода и конфигурации — GitHub

Комментарии (16)


  1. iamoblomov
    30.10.2023 08:32
    +1

    Про локальный сервер абсолютно согласен!


  1. Iv38
    30.10.2023 08:32

    Стоило ли вообще морочиться с Sonoff DW2? Вайфайный датчик на батарейках с заявленным временем автономной работы в 3 месяца. Уже это делает его ужасным.


    1. GenkaOk Автор
      30.10.2023 08:32

      Не знаю, где вы прочитали про 3 месяца автономной работы.
      Я установил этот датчик 17.12.2022, вчера второй раз поменял батарейки.
      Первый раз поменял батарейки летом.
      Практически полгода на двух батарейках для меня это отлично.

      Дверь открывается постоянно


      1. Iv38
        30.10.2023 08:32

        Видел у нескольких продавцов в описаниях что-то типа "3 месяца при 3-х срабатываниях в день". У самого Sonoff про время работы ни слова.

        Но по мне так и полгода это очень мало. Я в своих зигби-датчиках вообще ни разу не менял батарейки за я даже не помню сколько лет.


  1. KiLLWarez
    30.10.2023 08:32
    +1

    Прошивать Sonoff на ESP8266 для Home Assistant можно и без паяльника, сегодня делал на Mini, опишу на его примере.

    1. Создать устройство в ESPHome, дождаться компиляции прошивки, скачать бинарник.

    2. Установить приложение Ewelink на телефон, подключить устройство к сети, добавить в Ewelink.

    3. Обновить прошивку устройства через приложение, на момент написания 3.7.6 последняя, уже давно не обновлялась

    4. После обновления прошивки удалить устройство из Ewelink

    5. Нажать единственную кнопку (GPIO0 на Mini) на 5-10 секунд до постоянного моргания диода - Sonoff устройство перейдет в DIY Mode

    6. Подсмотреть IP адрес устройства в вашем роутере, возможно в приложении Ewelink тоже был виден адрес - не проверял

    7. Доступность устройства на IP адресе можно проверить браузером, там будет упрощенный веб-интерфейс для ввода SSID и пароля. Подготавливаем софт для отправки POST запроса устройству - Postman, curl, RESTer расширение Chrome и т.п.

    8. Отправить POST запрос на адрес устройства: URL - http://IP:8081/zeroconf/info, { "data": { } }. Вернется JSON с полем "otaUnlock": false. Пишут, что в структуре body нужно оправлять еще поле deviceid, но у меня с ним устройство не отвечало.

    9. Отправить POST запрос: URL - http://IP:8081/zeroconf/ota_unlock с body { "data": { } }

    10. Для Windows, cкачать и запустить локальный Nginх без настройки, положить бинарник прошивки в папку html. Nginx, потому что устройство читает файл прошивки с веб-сервера частями - фичу не умеют более простые приложения веб-сервера.

    11. Отправить POST запрос: URL - http://IP:8081/zeroconf/ota_flash с body
      { "data": {
      "downloadUrl": "http://NGINX_IP/firmware.bin",
      "sha256sum": "SHA256 hash прошивки " } }

    12. Смотрим в лог Nginx как устройство считывает прошивку частями. После окончания прошивки оно перезапустится и будет доступно в Home Assistant.


    1. iamoblomov
      30.10.2023 08:32

      к сожалению они не все диуай мод поддерживают,

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

      либо пусть нормальную документацию делают не требующую умения реверсить


  1. Krey
    30.10.2023 08:32

    В 2023 году уже есть zigbee3 и matter.


    1. sirota
      30.10.2023 08:32

      И они все ещё не имеют той гибкости и лёгкости прошивок заводских устройств по сравнению с esp подобными устройствами.


      1. Krey
        30.10.2023 08:32

        Их прошивать вообще не надо. Зачем?


        1. sirota
          30.10.2023 08:32

          1. Я так хочу.

          2. Повторяюсь - гибкость. Самое простое из последнего что я сделал - автовключение света перед двором. Датчик присутствия Ld2410, реле, датчик освещенности, wemos D1 mini + esphome. Автономное устройство логику которого я могу менять на лету и для прошивки не нужны программаторы + не ограничен функционалом скажем того же ptvo. А написание логики для еспхома вещь вполне интуитивная и не требует больших навыков программирования.

            С зигби а маттером вы так сможете?


          1. Iv38
            30.10.2023 08:32

            Не, когда есть внешнее питание и роутер под боком, который не перегружен несколькими десятками таких устройств, то ESP отличная штука вообще. И там производительный процессор, много памяти, большая скорость передачи данных - мечта DIY-щика. Особенно с современными либами. А вот вайфаные датчики на батарейках - это ерунда какая-то. Хотя и тут бывают исключения. Ватериус, например. Чтобы отправлять показания раз в сутки, много энергии не надо, зато вайфайность делает его доступным для широкого потребления.


            1. sirota
              30.10.2023 08:32
              +1

              В вопросе не было про "внешнее питание", "перегружен" и прочее. Был конкретный вопрос. 90% устройств УД у меня zigbe. Но все им не приткнешь, а если и можно на том же ptvo собрать, то будет и стоить дороже и функционалу ptvo до esphome ой как далеко.

              Простой пример. мне надо датчик CO2 и ик пульт в каждой комнате. Да зигби может предложить мне оба эти устройства, но с ценник будет... с esp это 1 устройство, которое вышло мне по цене в 1500р, немного 3д печати (для печати корпуса под датчик co2) и пара проводков. 1 устройство, которое вдруг еще и смогло взять на себя функцию датчика температуры и влажности. И все это от 1 розетки, кроме того сущность климата собрана в самом esphome и в ха залетает просто как устройство. И я могу продолжать управлять тем же сплитом с родного сплита, но в HA я тоже буду видеть изменения на сплите внесенные родным пультом. Зигби так не может пока (


              1. Iv38
                30.10.2023 08:32

                Полностью согласен


  1. vitiok78
    30.10.2023 08:32
    +2

    Я всё от Sonoff заменил на Aqara. Причём брал только устройства с ZigBee. Абсолютно все датчики Sonoff вызывают у меня недоумение своей работой от батареек. На датчиках движения я их менял чуть ли не раз в полтора месяца. Это никуда не годится. Aqara залетает в Home Assistant на ура. Батарейки уже год не менял ни на одном из множества своих датчиков.

    Наблюдение из моей практики: WiFi устройства - это постоянный геморрой.

    Поэтому всем совет: забываем про WiFi устройства, берём только устройства ZigBee, которые поддерживаются Home Assistant. Даже если это устройства от ноунеймов, то головной боли будет гораздо меньше. Тем более, не нужна никакая связь со внешними серверами, т.е. не нужно и лекарство от этой проблемы.


    1. Zuy
      30.10.2023 08:32

      Странно, но у меня абсолютно противоположный опыт. Все wifi и z-wave устройства работают крайне надёжно, а вот с ZigBee какие-то проблемы. В частности перебрал несколько датчиков температуры и влажности пока нашел те, которые не отваливались бы через пару месяцев. А вот датчики на открытие дверей попробовал три с Али, все отвалились через месяц. Сейчас заказал z-wave.

      Сеть у меня состоит из RPI с Sonoff ZigBee донглом в одном конце дома плюс ZigBee розетка работает как повторитель в другом конце.


  1. ABATAPA
    30.10.2023 08:32

    Зачем это, когда есть, к примеру, Tasmota?