Датчик наличия 220В на основе Wemos D1 и о перипетиях с чатом GPT
У моего товарища дома установлен инвертор Anenji на 6,2 кВт, батарея на несколько кВт и солнечные панели. В летнее время в солнечные дни дом становится независим от городской сети. Но в пасмурные дни и осенне-весенний период энергии не хватает.
Практически весь дом работает через инвертор, включая духовку, микроволновку, электроводонагреватель, полотенцесушитель и пр. Напрямую к городской сети подключено несколько розеток на всякий случай.
Понятно, что в случае отключения сети, когда на улице пасмурно, духовкой и прочими мощными электроприборами никто не пользуется. Но отключать полотенцесушитель и нагреватель воды бывает некому. На этих и нескольких других приборах стоят WiFi розетки Tuya, но отключением дистанционно никто не занимается.
В связи с этим, понадобилось некое устройство, которое бы следило за состоянием городской сети.
Как ни странно, но поиски в инете не увенчались успехом. Очевидно китайцы считают, что отключения электроэнергии в доме невозможно, а может по какой другой причине.
Конечно, можно было попробовать использовать WiFi розетку или какой-нибудь power meter. Но при отключении энергии эти устройства не могут дать сигнал в сценарий, чтобы отключить лишние приборы, а просто сами отключаются.
Еще одной идее было купить датчик открытия окон/дверей, заменить геркон на реле, которое бы питалось от сети. Но мне не нравится идея батареек и вообще…
Совершенно неожиданно на Али попалась плата Wemos с холдером под аккумулятор 18650. Недавно был небольшой обзор.

Почему бы не попробовать использовать ее, сделав совместимой со Smart Life. Идея простая, от плюса USB порта берем сигнал и подаем через делитель на один из пинов D. При наличии напряжения на блоке питания на нем устанавливается 1, при пропадании — 0. При этом устройство остается в сети, питаясь от аккумулятора, как обещает продавец до 17 часов. В Smart Life устройство меняет статус, что позволяет сценарию управлять WiFi розетками, в частности подключенными к электронагревателям.
Копаться на форумах и в документации Tuya мне было лень, поэтому решил обратиться к «умному» чату GPT. «Без проблем» сказал он, «сваяем скетч за пять минут».
Новый «умный интеллект» сразу выдал скетч.
Предполагалось, что устройство на Wemos будет вести себя также как любое совместимое. Т.е. просто новое устройство обнаруживается приложением, указывается данные WiFi и все начинает работать. Но не тут то было. Модуль категорически не хотел обнаруживаться. Очевидно, из-за того, что Wemos не имеет на борту Bluetooth или устройства Tuya работают по какому-то своему протоколу.
Что ж, идем с претензией к ИИ.
Нужно сказать, что все время ИИ выдавал исправленные скетчи без всякого пафоса в отличие от чата Gpt набивающего себе цену.
Поиск истины занял довольно большой промежуток времени и тысячи строк кода, которые выдавал ИИ. Были предпринята куча вариантов, вплоть до пробы связать Tasmota и Tuya.
И вот наконец окончательное решение:
Попробую воспроизвести последовательность действий. Возможно что-то пропущу, тогда у вас будет возможность проконсультироваться с ИИ.
И так, для начала нужно зайти на сайт разработчиков под своим логином в Smart Life и создать новый продукт.

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

Далее система перебрасывает на список стандартных функций для этого устройства. Но в моем случае ничего выбирать не нужно.
Нажав на Ок попадаем на страницу списка функций, где добавляем несколько кастомных.

Для моего проекта нужен некий switch со значением boolean и Value, в котором будет отображаться текущее напряжение аккумулятора. Важное замечание, параметр Data Transfer Type должен быть обязательно Send and Report.


Именно поэтому, я не стал выбирать из списка стандартных функций. Некоторые из них имеют свойство Report only, которое нельзя изменить. А это один из камней преткновения почему долго пришлось колдовать со скетчем. Но, в принципе, среди списка можно подобрать те, которые могут отправлять и принимать данные. Главное, чтобы они подходили под ваш проект. Также можно комбинировать стандартные и кастомные функции.
Выбираем панель, которая будет в Smart Life. Здесь можно настроить по своему усмотрению и даже загрузить свой рисунок. Получаем QRcode, который можно отсканировать в приложении и посмотреть как будет эта панель выглядеть.

Далее нужно выбрать тип устройства. И вот здесь возникла проблема: в списке нет ESP8266 или совместимого. Поэтому было предложено выбрать любое поддерживающее WiFi.

В визарде есть еще несколько шагов, но по-большому счету этого достаточно. Все остальное можно настроить позже.
Теперь необходимо добавить устройство в облачный проект. Именно через него и будет оно общаться с программой Smart Life или Tuya.
В разделе Cloud/Development создаем новый проект, если он еще не существовал.
После создания необходимо зайти в него. На странице Overview будут интересовать Access ID/Client ID и AccessSecret/Client Secret. Эти значения необходимы, чтобы получить доступ к облаку Tuya.

Теперь необходимо созданный выше девайс добавить в этот проект.
Нужно перейти на вкладку Devices, нажать Add Device и выбрать Virtual.

Из списка на вкладке My Products нужно выбрать созданный.

Откроется очередное окно с кучей вкладок с непонятными параметрами. Но нам нужна вкладка Add To Tuya App Account. Здесь будет сгенерирован QR code, который нужно отсканировать в приложении Smart Life.

После этого устройство появится на странице приложения.
На вкладке созданного виртуального устройства понадобится параметр Device ID.

Еще один подводный камень, о который споткнулись мы с ИИ. Определенные функции еще не отображаются в виртуальном устройстве. Соответственно, обратиться к ним пока невозможно.
Если зайти на вкладку Device Debugging она будет пустая.

Вверху станице написан довольно большой текст. Суть, нужно зайти на Product Details и выбрать режим DP Instruction.

Только после этого функции устройства появятся и только тогда с ними можно будет работать.

Устройства общаются с облаком Tuya посредством запросов GET/POST.
Прежде всего, нужно получить access_token. Структура примерно следующая:
GET openapi.tuyaeu.com/v1.0/token?grant_type=1
Headers: clientId, timestamp (от начала веков-1970 года) и подпись.
Подпись формируется как: clientId+«HmacSHA256»+method + "\n" + contentHash + "\n\n" + urlPath, где contentHash — некая пустая строка Hash.
Все это криптуется HmacSHA256 тем самым secret_key.
В результате получаем заветный access_token.
Чтобы отправить какие-либо данные в Smart Life используется
POST openapi.tuyaeu.com/v1.0/devices/{{deviceId}}/commands с теми же header.
В теле запроса указывается {«commands»:[{«code»:«status»,«value»:true}]} название функции, значение которой нужно передать.
Точно также формируется подпись, с включением тела запроса.
Выдан очередной довольно длинный скетч. Однако, в консоли Arduino IDE появляется ошибка: Ошибка получения токена: «request time is invalid».
Следующая ошибка: Ошибка получения токена: «code»:1004,«msg»:«sign invalid». Оказывается, что сервер Tuya требует обязательную HMAC-SHA256 подпись (sign) запроса. Еще один скетч.
Еще несколько ошибок, связанных все с тем же HMAC, то ему не хватает параметра при вызове, то он хочет, чтобы все символы были в UPPERCASE.
В итоге:
Но, это была передача только одного параметра: наличия напряжения. Следующей моей идее, было передавать текущее напряжение на аккумуляторе. И тут нас ждал очередные часы поиска истины.
Как мы с ИИ не бились, но Tuya возвращала ошибку
Ок, пересоздаем все и делаем параметр нужного свойства. Но ошибка так и не уходит. Мало того периодически появляются новые.
И наконец, вот он рабочий скетч для модуля Wemos D1!
Для того, чтобы модуль мог выходить из состояния глубокого сна, нужно GPIO16 (D0) соединить с пином Reset. Однако, ни первый ни второй не выведен на гребенку.

Я уже думал, что придется паяться к контактам самой микросхемы или дорожкам, но при изучении обнаружил площадку с двумя контактами, один из них соединялся с GPIO16, а второй с кнопкой Reset.

Так что, все свелось к соединению этих двух контактов.
В итоге, я выбрал одну стандартную функцию и одну кастомную для показа напряжения аккумулятора. В Smart Life это выглядит так:

Поскольку обе функции Read and Report, то в самом приложении их можно изменять. Если для первой это будет иметь значение, т.к. сработает сценарий, то изменение значения второй ничего не поменяет, потому что это значение не отправляется обратно в модуль.

Хочу сказать, что я на столько обленился, что даже очевидные ошибки, типа отсутствие нужной библиотеки при вызове функции не пробовал исправлять. Просто все ошибки, что выдавал Arduino IDE транслировались ИИ и тот тут же выдавал исправленный скетч. Кстати, любые ошибки с его стороны не только исправлялись, но и довольно подробно комментировались почему это произошло.
Но проверять и тестировать нужно тщательно. Например, в одном из предыдущих вариантов оказалось, что модуль вовсе не переходит в спящий режим. Потому что, после выполнения команды ESP.deepSleep() нужно сделать паузу, пока модуль перейдет в это самое состояние. Иначе начинает выполняться следующая команда и модуль никогда не переходит в сон. А ИИ сделал задержку до выполнения функции, а не после нее.
Время работы от аккумулятора оказалось примерно 17 часов, как и обещано на странице товара.
Ток потребления после перевода в сон составил чуть больше 9 мА.

Конечно скетч еще тестировать и тестировать. Тем не менее ИИ выдал вполне рабочий код и готов дорабатывать его по первому требованию. Например, я попросил вынести все константы в верх скетча, что было сделано практически мгновенно.
Уверен, что на изучение и перелопачивание всяких форумов по внедрению такого модуля в систему Tuya ушло бы гораздо больше сил и времени, чем пообщаться с ИИ.
Практически весь дом работает через инвертор, включая духовку, микроволновку, электроводонагреватель, полотенцесушитель и пр. Напрямую к городской сети подключено несколько розеток на всякий случай.
Понятно, что в случае отключения сети, когда на улице пасмурно, духовкой и прочими мощными электроприборами никто не пользуется. Но отключать полотенцесушитель и нагреватель воды бывает некому. На этих и нескольких других приборах стоят WiFi розетки Tuya, но отключением дистанционно никто не занимается.
В связи с этим, понадобилось некое устройство, которое бы следило за состоянием городской сети.
Как ни странно, но поиски в инете не увенчались успехом. Очевидно китайцы считают, что отключения электроэнергии в доме невозможно, а может по какой другой причине.
Конечно, можно было попробовать использовать WiFi розетку или какой-нибудь power meter. Но при отключении энергии эти устройства не могут дать сигнал в сценарий, чтобы отключить лишние приборы, а просто сами отключаются.
Еще одной идее было купить датчик открытия окон/дверей, заменить геркон на реле, которое бы питалось от сети. Но мне не нравится идея батареек и вообще…
Совершенно неожиданно на Али попалась плата Wemos с холдером под аккумулятор 18650. Недавно был небольшой обзор.

Почему бы не попробовать использовать ее, сделав совместимой со Smart Life. Идея простая, от плюса USB порта берем сигнал и подаем через делитель на один из пинов D. При наличии напряжения на блоке питания на нем устанавливается 1, при пропадании — 0. При этом устройство остается в сети, питаясь от аккумулятора, как обещает продавец до 17 часов. В Smart Life устройство меняет статус, что позволяет сценарию управлять WiFi розетками, в частности подключенными к электронагревателям.
Копаться на форумах и в документации Tuya мне было лень, поэтому решил обратиться к «умному» чату GPT. «Без проблем» сказал он, «сваяем скетч за пять минут».
И тут началось...
Прежде всего нужно создать проект на сайте девелоперов Tuya. ИИ подсказывал на какие кнопки нужно нажать и что сделать. Только вот этих самых кнопок не находилось на странице. Пришлось отправлять скриншоты. И тут чат прозрел, так у тебя новый интерфейс 2026 сайта! Странно, разве я могу использовать старый, если сайт обновился. Ну, ладно. Создал проект. Теперь нужно создать скетч. Опять же чат пообещал, что вот буквально сейчас все сделает. Только в бесплатной версии количество сообщений ограничено. А этот гад, не выдавал сразу код, а обещал это сделать быстро и без ошибок, и следующем сообщением приходилось ему говорить: Да, давай. В результате через какое-то непродолжительное время было предложено или перейти на платную версию или подождать буквально часов 12. В результате такими темпами вся эта котовасия заняла чуть ли не две недели.
Вариантов создания программы под Wemos было несколько. Вначале ИИ предложил сделать в VS Code + библиотеки. В результате выяснилось, что Tuya убрала поддержку ESP8266 из виндоуз версии. Пришлось ставить виртуальную машину Ubuntu. Но и там такой библиотеки не оказалось. Как будто не мог ИИ выяснить это сразу. Вернулись к Arduino IDE.
В созданном проекте Tuya нужно было добавить ESP8266 как новое устройство. И опять выясняется, что Tuya убрала поддержку именно этого модуля, осталась ESP32, хотя и это не гарантировано.
«Давай создадим виртуальный девайс — это займет 2 минуты!». Я разве против? Давай. И опять он забыл что у меня новый интерфейс и опять извинения, ой это моя ошибка и сейчас исправим за пять минут. И опять приходится ждать, пока в очередной раз пройдет время на использование бесплатной версии чата.
Через две недели мне все это надоело и я обратился к другому «умному» чату: Gemini. Здесь дело пошло веселее. И, хотя, частенько ИИ делал те же ошибки, что и предыдущий, первая рабочая версия скетча была готова в общей сложности часа через два.
Доведение до ума заняло еще довольно много времени. Но об этом позже.
Вариантов создания программы под Wemos было несколько. Вначале ИИ предложил сделать в VS Code + библиотеки. В результате выяснилось, что Tuya убрала поддержку ESP8266 из виндоуз версии. Пришлось ставить виртуальную машину Ubuntu. Но и там такой библиотеки не оказалось. Как будто не мог ИИ выяснить это сразу. Вернулись к Arduino IDE.
В созданном проекте Tuya нужно было добавить ESP8266 как новое устройство. И опять выясняется, что Tuya убрала поддержку именно этого модуля, осталась ESP32, хотя и это не гарантировано.
«Давай создадим виртуальный девайс — это займет 2 минуты!». Я разве против? Давай. И опять он забыл что у меня новый интерфейс и опять извинения, ой это моя ошибка и сейчас исправим за пять минут. И опять приходится ждать, пока в очередной раз пройдет время на использование бесплатной версии чата.
Через две недели мне все это надоело и я обратился к другому «умному» чату: Gemini. Здесь дело пошло веселее. И, хотя, частенько ИИ делал те же ошибки, что и предыдущий, первая рабочая версия скетча была готова в общей сложности часа через два.
Доведение до ума заняло еще довольно много времени. Но об этом позже.
Новый «умный интеллект» сразу выдал скетч.
Предполагалось, что устройство на Wemos будет вести себя также как любое совместимое. Т.е. просто новое устройство обнаруживается приложением, указывается данные WiFi и все начинает работать. Но не тут то было. Модуль категорически не хотел обнаруживаться. Очевидно, из-за того, что Wemos не имеет на борту Bluetooth или устройства Tuya работают по какому-то своему протоколу.
Что ж, идем с претензией к ИИ.
Нужно сказать, что все время ИИ выдавал исправленные скетчи без всякого пафоса в отличие от чата Gpt набивающего себе цену.
Поиск истины занял довольно большой промежуток времени и тысячи строк кода, которые выдавал ИИ. Были предпринята куча вариантов, вплоть до пробы связать Tasmota и Tuya.
И вот наконец окончательное решение:
Единственный стабильный способ заставить автономный ESP8266 работать с Tuya Cloud через код — использовать прямую авторизацию устройства по ключам (Device ID + Device Secret). В этом случае плата подключается к вашему Wi-Fi обычным кодом, а затем сразу авторизуется в вашем Cloud-проекте Tuya.
Попробую воспроизвести последовательность действий. Возможно что-то пропущу, тогда у вас будет возможность проконсультироваться с ИИ.
И так, для начала нужно зайти на сайт разработчиков под своим логином в Smart Life и создать новый продукт.

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

Далее система перебрасывает на список стандартных функций для этого устройства. Но в моем случае ничего выбирать не нужно.
Нажав на Ок попадаем на страницу списка функций, где добавляем несколько кастомных.
Для моего проекта нужен некий switch со значением boolean и Value, в котором будет отображаться текущее напряжение аккумулятора. Важное замечание, параметр Data Transfer Type должен быть обязательно Send and Report.


Именно поэтому, я не стал выбирать из списка стандартных функций. Некоторые из них имеют свойство Report only, которое нельзя изменить. А это один из камней преткновения почему долго пришлось колдовать со скетчем. Но, в принципе, среди списка можно подобрать те, которые могут отправлять и принимать данные. Главное, чтобы они подходили под ваш проект. Также можно комбинировать стандартные и кастомные функции.
Выбираем панель, которая будет в Smart Life. Здесь можно настроить по своему усмотрению и даже загрузить свой рисунок. Получаем QRcode, который можно отсканировать в приложении и посмотреть как будет эта панель выглядеть.

Далее нужно выбрать тип устройства. И вот здесь возникла проблема: в списке нет ESP8266 или совместимого. Поэтому было предложено выбрать любое поддерживающее WiFi.

В визарде есть еще несколько шагов, но по-большому счету этого достаточно. Все остальное можно настроить позже.
Теперь необходимо добавить устройство в облачный проект. Именно через него и будет оно общаться с программой Smart Life или Tuya.
В разделе Cloud/Development создаем новый проект, если он еще не существовал.
После создания необходимо зайти в него. На странице Overview будут интересовать Access ID/Client ID и AccessSecret/Client Secret. Эти значения необходимы, чтобы получить доступ к облаку Tuya.

Теперь необходимо созданный выше девайс добавить в этот проект.
Нужно перейти на вкладку Devices, нажать Add Device и выбрать Virtual.

Из списка на вкладке My Products нужно выбрать созданный.

Откроется очередное окно с кучей вкладок с непонятными параметрами. Но нам нужна вкладка Add To Tuya App Account. Здесь будет сгенерирован QR code, который нужно отсканировать в приложении Smart Life.

После этого устройство появится на странице приложения.
На вкладке созданного виртуального устройства понадобится параметр Device ID.

Еще один подводный камень, о который споткнулись мы с ИИ. Определенные функции еще не отображаются в виртуальном устройстве. Соответственно, обратиться к ним пока невозможно.
Если зайти на вкладку Device Debugging она будет пустая.

Вверху станице написан довольно большой текст. Суть, нужно зайти на Product Details и выбрать режим DP Instruction.

Только после этого функции устройства появятся и только тогда с ними можно будет работать.

Устройства общаются с облаком Tuya посредством запросов GET/POST.
Прежде всего, нужно получить access_token. Структура примерно следующая:
GET openapi.tuyaeu.com/v1.0/token?grant_type=1
Headers: clientId, timestamp (от начала веков-1970 года) и подпись.
Подпись формируется как: clientId+«HmacSHA256»+method + "\n" + contentHash + "\n\n" + urlPath, где contentHash — некая пустая строка Hash.
Все это криптуется HmacSHA256 тем самым secret_key.
В результате получаем заветный access_token.
Чтобы отправить какие-либо данные в Smart Life используется
POST openapi.tuyaeu.com/v1.0/devices/{{deviceId}}/commands с теми же header.
В теле запроса указывается {«commands»:[{«code»:«status»,«value»:true}]} название функции, значение которой нужно передать.
Точно также формируется подпись, с включением тела запроса.
Выдан очередной довольно длинный скетч. Однако, в консоли Arduino IDE появляется ошибка: Ошибка получения токена: «request time is invalid».
Отметка времени (Timestamp), которую отправляет Wemos D1, не совпадает с реальным временем на серверах Tuya (допустимый разрыв — не более нескольких секунд).И вновь новый скетч с несколькими добавленными строчками кода.
В коде использовался параметр millis(), который выдаёт время в миллисекундах с момента включения платы (например, 1500), а сервер Tuya ждёт реальное Unix UTC время в миллисекундах (13 цифр, например 1789474030676)
Следующая ошибка: Ошибка получения токена: «code»:1004,«msg»:«sign invalid». Оказывается, что сервер Tuya требует обязательную HMAC-SHA256 подпись (sign) запроса. Еще один скетч.
Еще несколько ошибок, связанных все с тем же HMAC, то ему не хватает параметра при вызове, то он хочет, чтобы все символы были в UPPERCASE.
В итоге:
$$\text{StringToSign} = \text{client\_id} + t + \text{HTTP\_METHOD} + \text{"\n"} + \text{Content-SHA256} + \text{"\n\n"} + \text{URI}$$Но, это была передача только одного параметра: наличия напряжения. Следующей моей идее, было передавать текущее напряжение на аккумуляторе. И тут нас ждал очередные часы поиска истины.
Как мы с ИИ не бились, но Tuya возвращала ошибку
{"code":2008,"msg":"command or value not support","success":false,"t":1790002210126,"tid":"be4c60a5b5cb11f18e74b24ed3ecc0bd"}И вновь несколько часов разборки полетов. В итоге, выяснилось, что я создал параметр со свойством Report only, вместо Send and Report. На мое возражение, что мы хотим просто читать параметр, а не записывать на модуль, был ответ что так работает система через облако. Ок, пересоздаем все и делаем параметр нужного свойства. Но ошибка так и не уходит. Мало того периодически появляются новые.
{"code":1108,"msg":"uri path invalid","success":false,"t":1790001646565,"tid":"6e69ff10b5ca11f1961972feba20a1c4"}И наконец, вот он рабочий скетч для модуля Wemos D1!
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <time.h>
#include <bearssl/bearssl.h>
// ============================================================================
// БЛОК КОНФИГУРАЦИИ И КОНСТАНТ
// ============================================================================
// 1. Параметры Wi-Fi
const char* WIFI_SSID = "xxx";
const char* WIFI_PASSWORD = "12345678";
// 2. Данные Tuya Cloud API
const char* TUYA_CLIENT_ID = "eq8pu8xxxxxxxxxxxx";
const char* TUYA_CLIENT_SECRET = "dcf65c9xxxxxxxxxxxxxxxxxxxx";
const char* TUYA_DEVICE_ID = "vdevo179xxxxxxxxxxxx";
// 3. Сетевые адреса и эндпоинты HTTP
const char* TUYA_HOST = "openapi.tuyaeu.com"; // Региональный сервер (Европа)
const char* TUYA_BASE_URL = "https://openapi.tuyaeu.com";
const char* NTP_SERVER_1 = "pool.ntp.org";
const char* NTP_SERVER_2 = "time.nist.gov";
// 4. Настройка аппаратных пинов
const int PIN_SENSOR_220V = 14; // GPIO14 (Пин D5 на Wemos D1)
const int PIN_BATTERY_ADC = A0; // Вход аналогового замера
// 5. Калибровка питания и логика Deep Sleep
const float BATTERY_CALIBRATION_FACTOR = 0.00412; // Коэффициент калибровки делителя A0
const float LOW_BATTERY_THRESHOLD = 3.1; // Порог разряда для ухода в сон (В)
const uint64_t DEEP_SLEEP_DURATION_US = 15ULL * 60ULL * 1000000ULL; // Время сна (15 минут в мкс)
// 6. Тайминги и системные параметры
const unsigned long BATTERY_CHECK_INTERVAL_MS = 60000; // Интервал замеров АКБ (60 сек)
const unsigned long DEBOUNCE_DELAY_MS = 50; // Задержка антидребезга (мс)
const unsigned long SERIAL_BAUD_RATE = 115200; // Скорость Serial
const char* EMPTY_BODY_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
// ============================================================================
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ СОСТОЯНИЯ
// ============================================================================
String access_token = "";
static bool last_state = HIGH;
unsigned long lastBatteryCheck = 0;
// ============================================================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
// ============================================================================
// HMAC-SHA256 (HEX в ВЕРХНЕМ регистре UPPERCASE)
String calculateHMAC(String data, String key) {
br_hmac_key_context kc;
br_hmac_context hc;
br_hmac_key_init(&kc, &br_sha256_vtable, key.c_str(), key.length());
br_hmac_init(&hc, &kc, 0);
br_hmac_update(&hc, data.c_str(), data.length());
uint8_t hmac_out[32];
br_hmac_out(&hc, hmac_out);
String hex_str = "";
for (int i = 0; i < 32; i++) {
if (hmac_out[i] < 0x10) hex_str += "0";
hex_str += String(hmac_out[i], HEX);
}
hex_str.toUpperCase();
return hex_str;
}
// SHA-256 для тела POST-запроса (в LOWERCASE)
String calculateSHA256(String data) {
br_sha256_context sc;
br_sha256_init(&sc);
br_sha256_update(&sc, data.c_str(), data.length());
uint8_t hash_out[32];
br_sha256_out(&sc, hash_out);
String hex_str = "";
for (int i = 0; i < 32; i++) {
if (hash_out[i] < 0x10) hex_str += "0";
hex_str += String(hash_out[i], HEX);
}
hex_str.toLowerCase();
return hex_str;
}
uint64_t getEpochMillis() {
time_t now = time(nullptr);
return ((uint64_t)now * 1000ULL);
}
// Безопасная функция ухода в глубокий сон
void goToSleep(uint64_t sleepTimeUs) {
Serial.println("-> Отключаем Wi-Fi и уходим в Deep Sleep...");
Serial.flush(); // Ждем полной отправки данных по Serial
// 1. Принудительно обесточиваем Wi-Fi радиомодуль
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(100); // Задержка для завершения аппаратного отключения радиомодуля
// 2. Переводим чип в глубокий сон
ESP.deepSleep(sleepTimeUs, WAKE_RF_DEFAULT);
// 3. Задержка ПОСЛЕ deepSleep блокирует поток до аппаратного отключения
delay(1000);
}
// Запрос авторизационного токена Tuya
void getTuyaToken() {
if (WiFi.status() != WL_CONNECTED) return;
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
String uri = "/v1.0/token?grant_type=1";
String url = String(TUYA_BASE_URL) + uri;
uint64_t t_now = getEpochMillis();
String t_str = String(t_now);
String strToSign = String(TUYA_CLIENT_ID) + t_str + "GET\n" + String(EMPTY_BODY_SHA256) + "\n\n" + uri;
String sign = calculateHMAC(strToSign, TUYA_CLIENT_SECRET);
http.begin(client, url);
http.addHeader("client_id", TUYA_CLIENT_ID);
http.addHeader("sign", sign);
http.addHeader("t", t_str);
http.addHeader("sign_method", "HMAC-SHA256");
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
if (doc["success"]) {
access_token = doc["result"]["access_token"].as<String>();
Serial.println("-> УСПЕХ: Токен Tuya успешно получен!");
} else {
Serial.print("-> Ошибка получения токена: ");
Serial.println(payload);
}
} else {
Serial.print("-> Ошибка HTTP запроса: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
// Универсальная функция отправки payloads в Tuya
void sendTuyaPayload(String jsonBody, bool isRetry = false) {
if (access_token == "") {
getTuyaToken();
}
if (access_token == "") {
Serial.println("-> Ошибка: Нет действительного токена доступа!");
return;
}
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
String uri = "/v1.0/devices/" + String(TUYA_DEVICE_ID) + "/commands";
String url = String(TUYA_BASE_URL) + uri;
uint64_t t_now = getEpochMillis();
String t_str = String(t_now);
String bodyHash = calculateSHA256(jsonBody);
String strToSign = String(TUYA_CLIENT_ID) + access_token + t_str + "POST\n" + bodyHash + "\n\n" + uri;
String sign = calculateHMAC(strToSign, TUYA_CLIENT_SECRET);
http.begin(client, url);
http.addHeader("client_id", TUYA_CLIENT_ID);
http.addHeader("access_token", access_token);
http.addHeader("sign", sign);
http.addHeader("t", t_str);
http.addHeader("sign_method", "HMAC-SHA256");
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST(jsonBody);
if (httpCode > 0) {
String payload = http.getString();
Serial.print("-> Ответ сервера Tuya: ");
Serial.println(payload);
DynamicJsonDocument doc(1024);
DeserializationError err = deserializeJson(doc, payload);
if (!err) {
if (doc["success"]) {
Serial.println("-> УСПЕХ: Команда доставлена!");
} else {
int errCode = doc["code"];
// Проверка истечения токена (код 1010)
if (errCode == 1010 || payload.indexOf("token invalid") != -1) {
if (!isRetry) {
Serial.println("-> ВНИМАНИЕ [1010]: Токен устарел. Запрашиваем новый...");
access_token = "";
getTuyaToken();
if (access_token != "") {
Serial.println("-> Повторная отправка команды с новым токеном...");
http.end();
sendTuyaPayload(jsonBody, true);
return;
}
} else {
Serial.println("-> Ошибка: Повторная отправка не удалась.");
}
}
}
}
} else {
Serial.print("-> Ошибка отправки: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
// Замер напряжения аккумулятора
float getBatteryVoltage() {
int rawADC = analogRead(PIN_BATTERY_ADC);
float voltage = rawADC * BATTERY_CALIBRATION_FACTOR;
return voltage;
}
// Замер батареи и обработка логики сна
void processBatteryTelemetry() {
float vBatt = getBatteryVoltage();
Serial.print("Считано с A0: ");
Serial.print(vBatt);
Serial.println(" В");
int tuyaValue = (int)(vBatt * 100);
String payload = "{\"commands\":[{\"code\":\"voltage_current\",\"value\":" + String(tuyaValue) + "}]}";
sendTuyaPayload(payload);
bool is220Present = (digitalRead(PIN_SENSOR_220V) == LOW);
if (vBatt < LOW_BATTERY_THRESHOLD) {
if (is220Present) {
Serial.println("-> Батарея разряжена, но 220V ЕСТЬ. Работаем и заряжаемся.");
} else {
Serial.println("-> КРИТИЧЕСКИЙ ЗАРЯД и 220V НЕТ! Вызываем Deep Sleep...");
goToSleep(DEEP_SLEEP_DURATION_US);
}
}
}
// ============================================================================
// SETUP И LOOP
// ============================================================================
void setup() {
Serial.begin(SERIAL_BAUD_RATE);
pinMode(PIN_SENSOR_220V, INPUT_PULLUP);
Serial.println("\nПодключение к Wi-Fi...");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi успешно подключен!");
configTime(0, 0, NTP_SERVER_1, NTP_SERVER_2);
Serial.print("Синхронизация времени");
time_t now = time(nullptr);
while (now < 100000) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("\nВремя синхронизировано!");
getTuyaToken();
// Инициализация состояний при старте/пробуждении
last_state = digitalRead(PIN_SENSOR_220V);
Serial.print("Текущее состояние 220V при старте: ");
Serial.println(last_state == LOW ? "ЕСТЬ" : "НЕТ");
String statePayload = "{\"commands\":[{\"code\":\"charge_switch\",\"value\":" + String(last_state == LOW ? "true" : "false") + "}]}";
sendTuyaPayload(statePayload);
processBatteryTelemetry();
lastBatteryCheck = millis();
}
void loop() {
// 1. Периодический замер напряжения аккумулятора
unsigned long currentMillis = millis();
if (currentMillis - lastBatteryCheck >= BATTERY_CHECK_INTERVAL_MS) {
lastBatteryCheck = currentMillis;
processBatteryTelemetry();
}
// 2. Отслеживание изменения уровня 220V
bool current_state = digitalRead(PIN_SENSOR_220V);
if (current_state != last_state) {
delay(DEBOUNCE_DELAY_MS);
if (digitalRead(PIN_SENSOR_220V) == current_state) {
last_state = current_state;
Serial.print("Изменение состояния 220V: ");
Serial.println(last_state == LOW ? "ЕСТЬ (LOW)" : "НЕТ (HIGH)");
String statePayload = "{\"commands\":[{\"code\":\"charge_switch\",\"value\":" + String(last_state == LOW ? "true" : "false") + "}]}";
sendTuyaPayload(statePayload);
if (last_state == HIGH) {
processBatteryTelemetry();
}
}
}
}
Для того, чтобы модуль мог выходить из состояния глубокого сна, нужно GPIO16 (D0) соединить с пином Reset. Однако, ни первый ни второй не выведен на гребенку.

Я уже думал, что придется паяться к контактам самой микросхемы или дорожкам, но при изучении обнаружил площадку с двумя контактами, один из них соединялся с GPIO16, а второй с кнопкой Reset.

Так что, все свелось к соединению этих двух контактов.
В итоге, я выбрал одну стандартную функцию и одну кастомную для показа напряжения аккумулятора. В Smart Life это выглядит так:

Поскольку обе функции Read and Report, то в самом приложении их можно изменять. Если для первой это будет иметь значение, т.к. сработает сценарий, то изменение значения второй ничего не поменяет, потому что это значение не отправляется обратно в модуль.

Хочу сказать, что я на столько обленился, что даже очевидные ошибки, типа отсутствие нужной библиотеки при вызове функции не пробовал исправлять. Просто все ошибки, что выдавал Arduino IDE транслировались ИИ и тот тут же выдавал исправленный скетч. Кстати, любые ошибки с его стороны не только исправлялись, но и довольно подробно комментировались почему это произошло.
Но проверять и тестировать нужно тщательно. Например, в одном из предыдущих вариантов оказалось, что модуль вовсе не переходит в спящий режим. Потому что, после выполнения команды ESP.deepSleep() нужно сделать паузу, пока модуль перейдет в это самое состояние. Иначе начинает выполняться следующая команда и модуль никогда не переходит в сон. А ИИ сделал задержку до выполнения функции, а не после нее.
Время работы от аккумулятора оказалось примерно 17 часов, как и обещано на странице товара.
Ток потребления после перевода в сон составил чуть больше 9 мА.

Конечно скетч еще тестировать и тестировать. Тем не менее ИИ выдал вполне рабочий код и готов дорабатывать его по первому требованию. Например, я попросил вынести все константы в верх скетча, что было сделано практически мгновенно.
Уверен, что на изучение и перелопачивание всяких форумов по внедрению такого модуля в систему Tuya ушло бы гораздо больше сил и времени, чем пообщаться с ИИ.
Самые обсуждаемые обзоры
Я автоматизации и карточки для HA так делаю с помощью бесплатного Gemini в поиске Google. Причём, он вполне способен сохранять контекст в течение для (и это примерно сотня страниц диалога). И конфиги для ESPHome тоже делал.
Да, порою нужны десятки итераций, нужно следить, чтобы самостоятельно не «ушёл налево» (не поменял метод достижения цели), отсеивать совсем уж очевидные ошибки… Но вариант «поставил задачу — скопировал код — заскриншотил ошибку/результат — скормил ИИ — скопировал код...» работает.
Ну или перейти с облачного smart life на православный Home Assistant, там возможно писать автоматизацию, основываясь на внезапной недоступности наблюдаемого устройства, так что умная розетка в городской сети была бы отличным индикатором и триггером для дальнейших действий.
Предлагаемый вариант — запитать «прибор» от того же, чем питается роутер. При просыпании раз в пять минут, мониторинге, репорте и засыпании это практически не увеличит расход от этого резерва, однако из схемы уйдёт лишний аккумулятор со своими проблемами — заряд, разряд, потеря ёмкости, вздутие… Далее не мерять присутствие напряжение в розетке, когда по факту инвертор уже фактически весь дом отключил, а мерять напряжение на АКБ, от которых инвертор дом питает. Это позволит не бороться с последствиями (дом обесточен полностью), а по мере разряда превентивно отключать мощные потребители, оставляя хоть что-то в доме работающем до последнего электрона в аккумуляторе.
Все подключено через инвертор. Чтобы в отсутствие городской сети не высаживать быстро аккумулятор отключаются нагревательные приборы, потребляющие большое количество энергии. Все остальное: холодильник, освещение, роутеры остаются подлючеными.
В сценарии можно еще учитывать время суток и погоду. Если это день и яркое солнце, то в принципе можно и не отключать что-то
Банальный фотоэлемент может дать инфу о кол-ве света, попадающего на панели, и это будет настоящая информация, т.к. вычислить кол-во энергии, попадающей на панели из погоды и времени суток фактически невозможно. Вычислить можно много всего, вплоть до угла падения солнечных лучей на панели — но каждое пролетающее облачко, затеняющее панели — вычислить невозможно.
Или тем же способом, которым вы еспшку туда подтянули.
Хотя от меня ускользает смысл в необходимости отдельного фотодатчика, если можно снимать данные о напряжении с панелей, которые к тому же сразу интегрированы текущей нагрузкой.
Вы получили на выходе кусок неподлерживаемого говна, черный ящик с неизвестным количеством изощренных багов, которые не найти никаким тестированием.
Хорошо только то, что неважно работает это всё или нет.
А главное, я получил как работает в принципе интеграция в Tuya без копания в различных форумах и документации.
ЗЫ. Про рабочий, протестированный и документированный код даже несмешно комментировать, он примерно также рабочий как специальные провода для колонок из натренерованной :) безкислородной :))) меди.
ЗЫЫ. Без труда и рыбку из пруда не вытащить. Если ты не работаешь — ты не работаешь :), если не учишься — не учишься. Двое из ларца могут имитировать работу, но ты никогда не узнаешь насколько плохо она сделана, у тебя просто нету компетенций, чтобы её оценить. Там где это неважно — это приемлимо. Хоть как-то, тоже вариант решения проблем. Но вот неважно ли там…
Документированный? Если комментарии есть, значит — документированный. Я тоже вайбкодил — агенты все свои блоки подписывают и указывают, что этот блок должен делать
Но судя по агрессии и уровню аргументации, вайбкодингом ты не никогда не занимался, не пробовал, но осуждаешь. Какую конкретно альтернативу предложишь? 5 лет учить программу ВУЗа по программированию, потом еще полгода изучать необходимый язык программирования, потом две недели читать документацию TUYA, ESP и так далее?
Чтобы что, чтобы считать себя тру программистом? Так это и есть бескилородная медь в аудиокабеле. Именно этот подход будет аудиофилией в чистом виде. А Вайбкодеры — они в этой метафоре просто купили себе аудиоколонку и просто слушают музыку, а не анонизмом бесполезным занимаются. Если решаемая задача решена, то что еще нужно то?
Из вашего поста видно, что вы зачем-то хотите казаться каким-то «тру программистом» при этом очевидно инженером вы не являетесь и не понимаете, что без понимания и чтения документации всё что можно сделать — это изготовить какую-то небезопасную поделку, как сделал автор всего этого.
Вам — не знаю.
Мне на месте автора нужна была бы уверенность, что не придется друга в закрытом гробу хоронить. Но ему и вам, наверное такая уверенность не нужна.
Как весело горят дома так, что не все успевают в трусах выскочить — тоже?
Никогда у вас не бахали адаптеры на 5в? (у меня с месяц назад бахнул огого, но без возгорания, однако корпус сорвало)
Итд итп.
Любая электрическая фигня пожароопасна.
Любой аккумулятор (а особенно литиевый обычный не лифепо и не лто) опасен ОЧЕНЬ. Можно было обойтись без этих рисков.
Но не тогда, когда ты вайбинженер.
ЗЫ. У меня тут пару лет назад примагнитилась иголка от галтовки к магнитному проводу для зарядки. Что я вам могу сказать. Адаптер дает 5в без умных протоколов. Я сомневаюсь, что иголка смогла умный протокол поддержать :), ну т.е. то к чему она примагнитилась +- там не было пинов. Несмотря на это нашел я ее т.к. она раскалилась до бела, прожгла ламинат на котором всё это лежало, расплавила корпус с магнитом итд итп.
От пяти заметьте вольт. Сварка — она тоже не от киловольт вообще-то.
Нет, почему-то у меня не взрываются USB адаптеры, причём они из розетки не вынимаются вообще никогда до замены на следющий, я не отключаю пол-дома, уходя, и так далее. Но даже если бахнет (уже шанс крайне мал) — чтобы было возгорание надо, чтобы он умел гореть (то есть был совсем левым — в нормальных корпус негорючий), чтобы при этом не вышиб автомат… В общем, шанс — как метеоритом по голове.
Аккумулятор эта штука может только разрядить насмерть — в предыдущем обзоре это обсуждали — защита от перезаряда там есть. И в любом случае к «вайбкодерству» это отношения не имеет — чисто электронная тема.
Есть такая штука — риск менеджмент. Какие риски я получаю, и что я получаю взамен.
В данной поделке пользователь получает кучу рисков. Если он их не в состоянии оценить — это его личное дело. Получает ли он сопоставимый гешефт — решать ему.
Аккумуляторы бывают разные, зарядки тоже, как работает именно эта штука именно автора никто не знает, а автор очевидно не проверял. Это в любом случае точка отказа. И будет ли с ним всё хорошо не знает никто. Но чтобы это понимать надо быть хоть чуть-чуть в теме, если ты вайбспециалист — увы, ты об этом даже не догадываешься. Тебе не с чего понимать что несет риски, а что нет, как организовать всё безопасно, что опасно, что неопасно итд итп. Беда испюлючительно в этом.
Причем если включить мозг, то можно избежать ВСЕХ этих рисков, сделать проще, быстрее, надежнее, дешевле. Но включать увы нечего, есть только вайб.
Про код даже начинать не хочется — это бессмысленно. Оно всегда чудовищно. Нейросети обучены на самых мрачных практиках, к сожалению. Похоже они там ответы со стековерфлоу в основном использовали.
Может ли нейросеть в руках специалиста дать ему некий буст — да.
Может ли нейросеть в руках неспециалиста дать ему некий буст — как правило нет.
Понимаете, это как с елочными игрушками :), ну т.е. вроде бы они такие-же как в детстве, вроде это всё должно работать, вроде выглядит прям неплохо, но нет, нету радости :), и копнешь тут, копнешь там, и волосы на башке начинают шевелиться, и только один вопрос «как это всё вообще работает», «как удалось хоть какие-то тесты пройти».
ЗЫ. Если чё — у меня есть платная подписка на курсор… и да — я ей пользуюсь. Но совершенно не так, как автор. И да — я ее сам оплачиваю.
Что до «точек отказа» и прочего — это всё красиво, конечно, но в нормальной квартире, тем более доме постоянно включённых электорнных устройств минимум десятки, если не сотни. Тем более, что и так торчат туевские розетки и куча всего остального, про которое тоже «будет ли хорошо не знает никто» — потому что непонятно, кто там что сэкономил при изготовлении. И аккумуляторного тоже наверняка полно — хоть датчиков, хоть лампочек, хоть ещё чего. Ну мир сейчас такой — в электронике буквально купаемся.
Перечитайте, там сверху довольно подробно всё разжевано.
Если у вас на зарядке нонстоп стоят 18650 банки, то могу только посочуствовать.
Вы очень смелый человек.
Насчёт зарядки нонстоп — ну убьёт она его, конечно, за какое-то время (за какое — вопрос отдельный). Но и только.
Коду, конечно, обработки ошибок бы добавить, но в остальном — ардуино как ардуино, ничего лучшего эта мелочь не достойна.
Наверное тем, что система глюконет, отключит бойлер и товарищ будет мыться холодной водой, заболеет и умрет. Но тогда причем здесь закрытый гроб?
Я для подобного проекта использовал wemos + вот такую оптопару.
https://aliexpress.ru/item/1005008543269512.html
Maxim_Sed верно заметил, что использовать оптопару- безопасное и правильное решение.
Так что проще, заменить все в щитке, установить ассистант или потратить две недели чтобы добавить еще одно устройство в существующую систему Tuya?
Но преодолевать порог входа в программирование, выгружать токены и т.д., чтобы… остаться привязанным к облаку? Эм, зачем, если эта задача в итоге с меньшими трудозатратами решается переводом всего в локальное управление, которое в перспективе дает гибкость и энергонезависимость в разу большую? Если уж не нужен центральный узел, то можно и две ESP напрямую между собой связать — первая будет датчиком напряжения, вторая реле умной розетки просто выключает, получая прямую команду от первой.
Ну вот сделана сейчас автоматизация через китайское облако. А если интернет в поселке отключится? А если чебурнет превратит вообще всю эту выполненную работу в тыкву? Локальный HA однажды настроенный хотя бы без обновлений, но продолжит работать и даже будет поддерживать дальнейшую настройку в рамках уже существующих функций — автоматизации можно будет дописывать, например.
Решает. И порождает набор других.
Если серьёзно — то кроме вопросов безопасности, надёжности и подобного если вообще возникают мысли об изготовлении своей железки — то почти наверняка это значит, что китай-облако переросли. Что дальше — делать что-то самому, кого-то нанимать или осознать ограничения и костылить — вопрос отдельный, но сам момент отрефлексировать стоит.
Но извинить не могу…
Как я ранее писал, вопрос в ценности трудозатрат — их вложение уже обязывает закладывать какой-то уровень надежности иначе становится сильно обидно за потраченное время, когда эти трудозатраты оказываются выкинуты в мусорку
Использовать для этого Node-RED, инвертор Victron, MQTT топик, Modbus, Телеграм (заблокированный в РФ), две SONOFF S60 и малинку сверху — вот решение данной проблемы без особых усилий.
При том, что по факту для этой автоматизации достаточно релюшки за сотку.
— он тоже стоит и питает квартиру когда нет ввода с города
— каюсь, реле проектировал 7 лет назад, хотя нет, не каюсь, работает без нареканий
— не все живут в РФ
— и 20-30 метров провода если точка подключения бойлера и ввод городской сети не в одном щитке,
проблему проводов решают а только если хочется Home Assistant который умеет не только бойлер выключать.
А вообще, вы правы, каждый выбирает то решение которое его устраивает по цене, удобству или любым други критериям.
300 рублей, 100% надежность.
Приезжайте, я вам заплачу в сто раз брльше. Только чур если вы загорбите чистовой ремонт — переделка за ваш счет. (Намекну — вы неминуемо попадаете на пол миллиона денЯк)
Может считать не цену кабеля, а цену прокладки :)? Она… разная.
Мне вообще непонятен смысл этих телодвижений.
Сильно проще либо переключить некритичные потребители ДО ИБП, либо включить их через магнитный пускатель, управляемый напряжением городской сети.
Зачем плодить избыточные сущности?
Разговор о разводке по дому.
Разве у меня не то же самое написано?
Эта релюшка замыкает контакты от трёхсотрублёвого реле, совместимого со Смартлайф, которые (контакты) должны идти на комнатный выключатель. Итого питание пропадает, реле размыкаект контакты, туевское реле думает, что выключатель выключили и отправляет сигнал об этом в смартлайф, а дальше уже автоматизация по выключению потребителей с помощью умных розеток.
А можно вообще реле типа сонофф, на которые можно 220В подать. Питание реле только надо сделать после ИБП, а контакт S1 или S2, не помню уже — туда подать фазу до ИБП. Т.о. реле останется работать, а 220В на неё перестанет приходить и она сработает.
C нормально разомкнутыми постоянно включенными в цепь 220 от розетки так получится, но глупо как-то держать соленоид 24/7 месяцами греющим комнату, они на такое не рассчитаны даже обычно.
Весь дом от инвертора, «включая духовку, микроволновку, электроводонагреватель, полотенцесушитель и пр.?» Под пр. еще легко наберется 2-3 кВт и больше: свет, ТВ, холодос, роутер, ноут, кондей, чайник. Итого легко под 10кВт выйдет. Запрещать включать духовку, если работает микроволновка и/или чайник?
А не проще ли все мощное пустить на отдельные группы минуя инвертор, и не делать мозг с одновременной их работой и вот этими костылями?
Но кроме нее существует бойлер, полотенцесушитель. А включены они через инвертор для того, чтобы использовать солнечную энергию, а не тянуть из сети.
И естественно, никто не включает одновременно духовку, чайник, микроволновку и пр. Так что инвертора на 6кВт хватает за глаза.
Дом сто квадратов, одна фаза 5 КВт на все, ни разу в жизни с недостатком подводимой мощности не сталкивался.
ПММ — 1,5 кВт
Стиральная машина — 1,5 кВт
Сушильная машина — 0,5 кВт
Водонагреватель — 1,0 кВт (в норм режиме, в турбо — 1,5 кВт)
Духовой шкаф — до 3,5 кВт
Варочная панель индукционная — до 5 кВт
Кондиционеры в режиме отопления (по жду магистрального газа — так) и охлаждения (а тут газ не поможет) 3 шт. 9000 BTU, 2 шт. 12000 BTU. Благо инверторные. Мощность потребления в разном режиме можно погуглить, они примерно типовые у всех производителей.
И вот наступает день стирки и готовки, жена загрузила стиралку, запустила ПММ, начала готовить и стряпать. Кондиционеры и водонагреватель в этот момент включаются вообще произвольно по велению своих контроллеров.
З.Ы.
Очень часто вижу, что люди не понимают разницу между агентом и моделью.
И то на что автор потратил две недели, нормальный агент (opencode, mimocode, kilocode, etc..) сделал бы за день — два, а то и быстрее. Просто за счет того что весь процесс был не прерывным и косяки решал бы сам агент.
И экономия тоже неплохая, в летнее время от сети можно отключиться вовсе
Но главное, это энергонезависимость от городской сети
p.s. можно подумать инверторы и панели не дорожают.
Ну не знаю. Я далеко не самый богатый, но оплата электричества — это копейки.
По деревням/поселкам вся разводка на воздушке, плюс куча деревьев, как ураган/мокрый снег/ледяной дождь, так массовые обрывы и отключения. В мае на соседней улице 3 дня не было ээ, слишком много обрывов, до них долго очередь доходила. При этом даже с газовым котлом насосы стоят и ээ нужна.Так что вопрос не пр заработать.
А если это единственное жилье, отопление котлом и вода в системе, то ситуация совсем другая.
Заморочиться уже имеет смысл, собственно после такой ситуации я и заморочился, когда в апреле 3 дня света не было и температура — 5 на улице.
Так что цена тут далеко не во главе угла оказывается.
Кроме того, если нет водопровода, а только скважина, то вы остаетесь не только в холодном доме, но еще и без воды, а значит элементарно сходить в туалет.
И частный сектор — это не только деревня…
Взаимодействие банальное: на входе или выходе моих ESP стоят устройства Aqara, которые общаются меж собой через собственный шлюз. Ну, а моя система — оповещения (лет 12 назад большая часть датчиков Aqara была только с привязкой к Китаю, и с уведомлениями плохо), управление по более сложным сценариям, получение и сопоставление данных от разных датчиков, не только Aqara.
К ESP всегда нужны датчики, а эти просто умнее обычных. Потому прграммы самые обычные.
Сейчас бы тоже делал на Tuya, но пока ничего не ломается. Кроме интернета, конечно.
Либо, если хочется беспровода, и домовая сеть нельзя подвергнуть модернизации (разделить мощные линии от немощных) — обычное реле на каждый потребитель + несколько приёмников радиореле 433 МГц. Передатчик ставится в щитке или любом удобном месте, появилась городская сеть — послать команду «активировать канал». Все приёмники, соответственно, настроены на этот канал, и включают мощное оборудование. Пропала городская сеть — послать команду «отключить канал»…
Оба варианта не требуют никакого дополнительного питания в виде аккумуляторов или батареек — питаются от городской же сети.
Комментарии не читали? Там 10 раз сказано, что ВСЕ устройства (кроме нескольких «аварийных» розеток) постоянно запитаны от инвертора, проводка имеющаяся, развести отдельно не представляется возможным.
Вы правда думали, что настолько умнее автора и он о таком не думал?
Ну вот, дошло хоть что-то, наконец.
Зачем, если у человека есть умный дом и он хочет, чтобы всё это можно было контролировать и всем управлять? А не вот эти дешёвые передатчики, которые могут сработать от звонка соседей, пульта от гаража, радиовыключателя и т. д. Человек не хочет этих древностей, он хочет современного и понятного (ему, прежде всего) решения. Вы не способны понять и принять такой вариант?
Так он это и делает, только современными средствами (лучший ли он сделал выбор — иной вопрос): это всё интегрируется в «умный дом», наглядно отображается состояние, всем этим можно управлять вручную, пишутся логи (что помогает разбирать нештатные ситуации или просто посмотреть статистику), состав «мощного оборудования» можно поменять просто в коде автоматизации без аппаратных переключений…
В умной розетке нет статуса при отключении электричества. Устройство оказывается offline и послать ничего не может, а другое устройство, например, другая умная розетка ничего опрашивать не умеет. Сценарии в интерфейсе Smartlife со статусом «offline» не делаются.
У меня была похожая задача и решилась отдельной розеткой, которая отключается одновременно с городской сети.
Но я понятия не имею, какие там в туе ограничения и где выполняются правила — у меня HomeAssistant, и все правила на нём.
Ну вот типа этого реле
Работает безотказно)
Когда включают напряжение в сети, генератор отключается от нее, и ему еще нужно какое-то время, что бы сработал блок управления и заглушил его ;)
Пока эта система работает много лет безотказно, ттт)
Путь к ней(к этой системе), был долог и тернист)))
Ровно до момента выхода из строя ИБП, аккумуляторов, генератора…
И АКБ не сдохнут ни разу, так как они тяговые, а не стартерные, которые предназначены для ИБП!
Такая связка работает уже очень давно и безотказно, больше 7 лет точно.
Так что ваш сарказм тут не уместен, и мнение диванных экспертов меня не волнует!
Ну, самое время.
Так тогда держите своё мнение при себе. А остальные тут вправе обсуждать написанное в том числе и Вами.
пы.сы. Ну а если деньги есть берем esp32-s3
отсутствие пакетов от этих розеток означает, что они отключились по причине отсутствия питания.
особенно если таких устройств несколько.
И кстати, то ли глюк какой-то, то ли еще что, но эти розетки периодически отваливаются хоть и на непродолжительное время. Я делал оповещение в ТГ при пропадании/появлении электричества с помощью mikrotika, который постоянно пинговал одну из розеток. Так вот, было довольно много ложных срабатываний.
Нужно подключить одну розетку к городской сети (до рубильника). При пропадании электричества она как тригер будет отключать другие устройства. Там много условий можно поставить.
А если на улице пасмурно, отслеживать так же, нужно только ещё одну розетку подключить к солнечным панелям и мерять там напряжение. Отключать при пороге. Правда там 12 вольт и розетку нужно переделать на это напряжение.
Изображение под спойлером не открывается, поэтому прикрепил так.
Сценарий должен быть на опросе статуса устройства — есть оно в сети или нет. Если одно устройство Т34 «offline», тогда выключить второе устройство Т34.
Сейчас снова посмотрел сценарии в приложении, то ничего нового там не добавилось. Можно отслеживать состояния «ON» и «OFF» и «Countdown».
Ну а пускатель в современном жилом доме может быть исключительно из-за фобии на электронику.
Установлен в щитке на «ввод» в квартиру работает как счётчик при пропадании электричества успевает отдавать в zigbee сеть показания напряжения 30~60В. Не говоря о том что он постоянно шлёт показания