Живу в новостройке и пока тут идут ремонты, изредка, но бывает, что отключается электричество. Чтобы умный дом продолжал работать (а вместе с ним и домашний интернет), купил себе мобильный UPS на AliExpress и немного его доработал.

У безымянного устройства (у меня 18 ваттная младшая модель) следующие характеристики:

  • Емкость: 10400 мАч

  • Входное напряжение: AC85–265В 50/60 Гц

  • Выход: USB 5В 2A

  • Выход: 5В 1A, 9В 1A, 12В 1A

  • Выход POE: 15В 0.6А, 24В 0.6А

Обзоры на это устройство можно найти в сети.

Итак, дано:

  1. Роутер Archer AX53 (питание 12В)

  2. Абонентский терминал SNR ONU-EPON-1G-mini (питание 12В)

  3. Raspberry Pi4 (питание USB)

Именно эти устройства я запланировал подключить через этот ИБП.

Вся слаботочка у меня находится на антресольной полке и чтобы, например, перезагрузить RPi4 или роутер приходится ставить стремянку, неудобно.

Решено было доработать устройство: первое чтобы UPS сообщал о своем уровне заряда и статус подключения к сети 220В, второе это возможность перезагружать по внешнему сигналу подключенное к USB выходу устройство, в моем случае - Raspberry Pi4 с установленным на нем умным домом, если вдруг он зависнет.

В заначке у меня нашлось: wemos d1 mini - будущие мозги, Pololu LV - микро цифровая кнопка, hw-384 - dc dc преобразователь, DHT11 - датчик температуры и влажности.

Использовал комплектующие, которые уже были у меня в наличии, поэтому некоторые подключения могут быть не совсем верными (без подтягивающих резисторов и фильтрующих конденсаторов). Возможно можно было использовать другие датчики и реле для отключения USB, вместо DCDC преобразователя использовать простой USB разъем. Но имеем, что имеем.

Спасибо нашим китайским друзьям, которые оставили нераспаенный разъем со всеми нужными сигналами от UPS (снизу вверх): Земля, питание 3.3 В, D25 - сигнал со светодиода 25%; W50, C75, 100 - сигнал со светодиодов 50%, 75%, 100% соответственно. R - красный светодиод, сигнал об отсутствии сети 220В, G - зеленый светодиод, сигнал о наличии 220В.

Первым делом выкидываем плату PoE-инжектора (она мне все равно не нужна, нет таких устройств), на его место отлично встает wemos d1:

Пропилил отверстие для будущего нового управляемого USB разъема:

потом залил все это термоклеем
потом залил все это термоклеем

Припаял сигнальные провода к основной плате:

подальше от высоковольтной части
подальше от высоковольтной части

И все вместе в сборке:

Принципиальная схема проапгреженного устройства:

Схема очень простая: Wemos питается от главной платы напряжением 3.3В, инвертированные сигналы 25%-100% и Red передаются на вход микрокомпьютера и считываются с определённой периодичностью. Питанием 8В (раньше туда подключался инжектор PoE) поступает на вход цифрового микровыключателя Pololu LV и через управляющий сигнал Cntrl включает или выключает свои мосфеты, соответственно подавая 8В на вход DC-DC преобразователя hw-384 (на выходе USB получаем 5В). Ну и еще подключен цифровой датчик температуры и влажности DHT11 (на всякий пожарный), у которого, для уменьшения толщины, я снял корпус и приклеил поверх аккумуляторов.

При обращении по IP адресу устройства можно посмотреть его состояние и вручную "перезагрузить" подключенное к новому USB разъему устройство. Так же эти данные рассылаются по протоколу MQTT в умный дом.

Также устройством можно управлять через телеграм бот.

Полный код для управления UPS
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <UniversalTelegramBot.h>

const char* ssid = "ВАШАСЕТЬ";        // Имя вашей Wi-Fi сети
const char* password = "ПАРОЛЬWIFI";  // Пароль для вашей Wi-Fi сети

const char* mqttServer = "IP";             // IP-адрес MQTT-сервера
const char* mqttUsername = "mqtt";         // Логин MQTT-сервера
const char* mqttPassword = "mqtt";         // Пароль MQTT-сервера
const char* mqttClientID = "ups";          // Идентификатор клиента MQTT
const char* mqttTopic = "battery/charge";  // Топик MQTT для публикации данных о батарее
const char* mqttTopicH = "battery/health"; // Топик MQTT для публикации данных о температуре
const int mqttPort = 1883;                 // Порт MQTT-сервера

const char* botToken = "TOKEN"; // Токен для телеграм бота
const char* chatId = "CHATID";   // чат бота
const unsigned long BOT_MTBS = 1000; // интервал обработки сообщений от бота
unsigned long botLasttime;

#define DHTPIN D4     // Пин, к которому подключен датчик DHT11
#define DHTTYPE DHT11 // Тип датчика DHT

const int batteryPin1 = D1;  // Пин входа для первого инвертированного сигнала 25%
const int batteryPin2 = D2;  // Пин входа для второго инвертированного сигнала 50%
const int batteryPin3 = D5;  // Пин входа для третьего инвертированного сигнала 70%
const int batteryPin4 = D6;  // Пин входа для четвертого инвертированного сигнала 100%
const int noPowerPin = D7;   // Пин входа для сигнала об отсутствии напряжения 220В

const int outputPin = D8;    // Пин вывода для отправки сигнала отключения линии USB

int battery=0;
bool noPower=false;
unsigned int unsuccessfullAttempts = 0;
float humidity;
float temperature;

const int maxAttempt = 25;
const unsigned long MQTT_SEND_INTERVAL = 8000;
unsigned long previousMillis = 0;

X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure secureClient;
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE);
ESP8266WebServer server(80);
UniversalTelegramBot bot(botToken, secureClient);

// перезагрузка устройства (прерывание питания USB) через Pololu Switch LV
void restartUSBdevice() {
  String html = "<html><head><meta charset=\"utf-8\"></head><body>";
  html += "Идет перезагрузка USB устройства...</body>";  

  bot.sendMessage(chatId, "Идет перезагрузка устройства подключенного к USB", "");

  digitalWrite(outputPin, LOW);
  delay(2000);
  digitalWrite(outputPin, HIGH);  

  server.sendHeader("Location", String("/"), true);
  server.send( 302, "text/html", html);
}
// обработка сообщений от Телеграм бота
void handleNewMessages(int numNewMessages)
{
  for (int i = 0; i < numNewMessages; i++){
    String chat_id = bot.messages[i].chat_id;
    String text = bot.messages[i].text;
    if (bot.messages[i].type == "callback_query"){
      text = bot.messages[i].text;
    } 
    if (text == "/health") {
      String text = "Состояние UPS:\n";
      if (noPower) text +="Сеть 220 отсутствует\n";
      else text +="Сеть 220 подключена\n";

      text +="Уровень заряда - "+String(battery)+"%\n";
      text +="Температура - "+String(temperature)+"\n";
      text +="Влажность - "+String(humidity)+"%";
      
      bot.sendMessage(chat_id, text, "Markdown");
    }
    if (text == "/rebootUSB"){
      restartUSBdevice();
    }    
  }
}

// Функция обработчика HTTP запроса
void handleRoot() {
  String html = "<html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"15\"></head><title>Умный UPS</title><body>";
  html += "<h3>Уровень заряда:</h1>";
  html += "<p>" + String(battery) + "%</p>";
  if (noPower){
    html += "<h3 style=\"color:red;\">Нет сети 220В</h3>";
  }
  if (unsuccessfullAttempts>0)
    html += "<h3>Попытка " + String(unsuccessfullAttempts) + " соединиться с MQTT</h3>";
  else
    html += "<h3>Соединение с MQTT OK</h3>";
  html += "<p>Температура: " + String(temperature) + "</p>";
  html += "<p>Влажность: " + String(humidity) + "</p>";
  html +="<form action=\"/restart\">";
  html += "<button type=\"submit\">Перезагрузить устройство подключенное к USB</button>";
  html +="</form>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void setup() {

  pinMode(batteryPin1, INPUT); // Инвертированный вход
  pinMode(batteryPin2, INPUT); // Инвертированный вход
  pinMode(batteryPin3, INPUT); // Инвертированный вход
  pinMode(batteryPin4, INPUT); // Инвертированный вход
  pinMode(noPowerPin, INPUT);  // Инвертированный вход
  
  pinMode(outputPin, OUTPUT);         // Установка пина вывода как выход
  digitalWrite(outputPin, HIGH);      // Включаем питание на USB

  Serial.begin(115200);
  delay(10);

  WiFi.begin(ssid, password);  // Подключение к Wi-Fi сети
  secureClient.setTrustAnchors(&cert);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("Connected to WiFi!");

  Serial.print("Retrieving time: ");
  configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  Serial.println(now);

  server.on("/", handleRoot);
  server.on("/restart", restartUSBdevice);
  server.begin();   
  client.setServer(mqttServer, mqttPort);

  bot.sendMessage(chatId, "Умный UPS запущен", "");
}

void loop() {

  client.loop();
  
  server.handleClient();

  unsigned long currentMillis = millis();

  // обработка вх сообщений от бота
  if (currentMillis - botLasttime > BOT_MTBS) {
    botLasttime = currentMillis;
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    while (numNewMessages){
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
  } 
  // основная обработка 
  if (currentMillis - previousMillis > MQTT_SEND_INTERVAL) {    
    previousMillis = currentMillis;
    if (!client.connected()) {
      // Переподключение к MQTT-серверу при разрыве соединения
      while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        if (client.connect(mqttClientID, mqttUsername, mqttPassword)) {
          Serial.println("connected");
          unsuccessfullAttempts=0;
        } else {
          unsuccessfullAttempts++;
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" retrying in 5 seconds");
          delay(5000);
        }
      }
    }
    //_______________________________________________________________________
    //_____________________проверка уровня заряда UPS________________________
    //_______________________________________________________________________
    bool charge25 = !digitalRead(batteryPin1);
    bool charge50 = !digitalRead(batteryPin2);
    bool charge70 = !digitalRead(batteryPin3);
    bool charge100 = !digitalRead(batteryPin4);
    noPower = !digitalRead(noPowerPin);
  
    char payload[50];

    if (charge100) {
      battery = 100;
    } else if (charge70) {
      battery = 70;
    } else if (charge50) {
      battery = 50;
    } else if (charge25) {
      battery = 25;
    }
    snprintf(payload, sizeof(payload), "{\"noPower\":\"%s\",\"battery\":%d}",  noPower ? "true" : "false", battery);  // Форматирование данных в формат JSON
    Serial.println("Publishing data to MQTT...");
    client.publish(mqttTopic, payload);  // Отправка данных на MQTT-сервер
    Serial.println("Data published to MQTT");
    //_____________________________________________________
    //________________датчик температуры___________________
    //_____________________________________________________
    humidity = dht.readHumidity();  // Чтение влажности
    temperature = dht.readTemperature();  // Чтение температуры по Цельсию

    if (isnan(humidity) || isnan(temperature)) {
      Serial.println("Failed to read from DHT sensor!");
    }

    Serial.println("Publishing data to MQTT...");
    snprintf(payload, sizeof(payload), "{\"humidity\":%.2f,\"temperature\":%.2f}", humidity, temperature);  // Форматирование данных в формат JSON
    client.publish(mqttTopicH, payload);  // Отправка данных на MQTT-сервер
    Serial.println("Data published to MQTT");

    if (unsuccessfullAttempts > maxAttempt){
      String keyboardJson = "[[{ \"text\" : \"Перезагрузить USB устройство\", \"callback_data\" : \"/rebootUSB\" }]]";
      bot.sendMessageWithInlineKeyboard(chatId, "Похоже, что HA не отвечает", "", keyboardJson);
    }

  }
  
}

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


  1. anonymous
    16.07.2023 20:51

    НЛО прилетело и опубликовало эту надпись здесь


    1. foxyrus Автор
      16.07.2023 20:51
      +4

      В алгоритм работы устройства я не вмешиваюсь (само по себе оно не умное), только считываю показания заряда и управляю отельным портом USB.


      1. alexval2007
        16.07.2023 20:51

        Попробуйте Аккумуляторы LiFePO4 считаются почти безопасными от пожара


        1. foxyrus Автор
          16.07.2023 20:51

          Да, посмотрел. Сварочный аппарат минимум стоит 2000 руб.


          1. Tomatos
            16.07.2023 20:51
            +1

            Дешевле нового шкафа =)


            1. foxyrus Автор
              16.07.2023 20:51

              Это да, сейчас температура на батареях, в закрытом шкафу 38.30


  1. Pest85
    16.07.2023 20:51
    +3

    Какое время работы обеспечивает от батареи?


    1. foxyrus Автор
      16.07.2023 20:51

      Специально не тестировал, думаю небольшое (у меня младшая модель), но этого точно хватит для того чтобы пережить отключение электричества.


    1. foxyrus Автор
      16.07.2023 20:51

      Тут в обзоре https://youtu.be/GapNFFRMRWQ?t=486


  1. NikaLapka
    16.07.2023 20:51
    +2

    Почему нельзя было купить, какой-нить AccordTec ББП-10 и любой 12В аккумулятор под нужный размер? Вышло бы в два раза дешевле и всё было бы хотя бы сертифицировано в соответствии с нормативными документами, а не чудо Китайской электроники с алиэкспресс.


    1. iig
      16.07.2023 20:51
      +1

      Для питания роутера от 12 В нужна специальная сертификация? ;)
      Конечно, 100500 способов решения задачи можно придумать. Повербанк, DC-DC преобразователь, пара ключей и esp, как же без него в умном доме ;) А тут все в одном корпусе. Удобно.


      1. AlexanderS
        16.07.2023 20:51
        +4

        Сертификация нужна чтобы ненароком не вернуться в свой сгоревший дом. Я бы тоже сильно подумал оставлять ли включенным на постоянку ИБП на литии.


        1. red_dragon
          16.07.2023 20:51

          Сертификация не является панацеей от пожаров, наводнений и прочих неприятностей, к сожалению. Буквально две недели назад, в конторе у нас, загорелся сертифицированный ИБП с кислотным аккумулятором (горел именно последний). И даже будучи засунутым в ведро с водой долго ещё чадил ядовитым дымом и заметно нагрел холодную воду.


          1. AlexanderS
            16.07.2023 20:51

            Конечно не является. Но это хоть какой-то фильтр от всякого китайского поделия, собираемого непонятно на чём и управляемого непонятно какими алгоритмами.


    1. foxyrus Автор
      16.07.2023 20:51
      +1

      Дешевле?


      1. shaggyone
        16.07.2023 20:51
        +1

        Может и не дешевле, и по габаритам побольше, но со свинцовой батареей куда меньше риск внезапно получить в фейерверк размером со всю квартиру целиком.


    1. SpiderEkb
      16.07.2023 20:51

      Ну вообще приличный ИБП стоит сильно дороже.

      Правда, я с квартирой не сталкивался, делал у себя в доме. И он тянет куда больше чем просто роутер. Фактически - насос в скважине (работает в паре с ГА т.е. в импульсном режиме), аэратор в ЛОС (там мощность порядка 60Вт и розетки в кабинете (три ноута, два внешних монитора, роутер, коммутатор, настольные лампы, можно зарядки гаджетов подключить).

      Так вот все это (инвертор с чистым синусом 3000ВА + 2 AGP АКБ 12В 100Ач + балансир для последовательно подключенных АКБ) не сказать чтобы очень бюджетно вышло.

      Но надежно и тянет 6-8 часов без проблем.


    1. jo_b1ack
      16.07.2023 20:51

      пожалуй плюсану за ББП, свинец проверен годами, а китайский литий под напряжением не особо


    1. xSVPx
      16.07.2023 20:51
      +1

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

      В целом "полный бардак и никакого доверия".

      Боитесь обычного лития - есть lto... Но в целом при нормальных балансирах итп опасности он не представляет, особенно в виде "банок".


  1. Kill_Voice
    16.07.2023 20:51

    Хм, откуда там 10400? Это ж обычный повербанк с преобразователем. В целом ИБП на литиевых аккумуляторах выглядит весьма опасно, так как при скачке напряжения может и бахнуть так, что не потушите


  1. nikolz
    16.07.2023 20:51

    можно такой

    а это для 5 вольт


  1. buldo
    16.07.2023 20:51

    В поисках готового ups на 12В на lifepo4.

    Если кто знает варианты - напишите, плиз


    1. p0isk
      16.07.2023 20:51

      Рекомендую посмотреть на ноутбуки, у которых батарея 4s. Плюсы:

      • полный контроль за уровнем заряда

      • ёмкость батареи можно увеличть, подключив дополнительные банки

      • из п.1: возможность интеграции в умный дом

      Минусы:

      • батарея на Li-Ion. Не видел ноутбуков на LiFePO4


      1. buldo
        16.07.2023 20:51

        Мне нужен ups для роутера и NAS :)


        1. p0isk
          16.07.2023 20:51

          Будет три-в-одном)


          1. buldo
            16.07.2023 20:51

            В ноут не воткнуть четыре 3.5" диска из моего synology :)


      1. 1CHer
        16.07.2023 20:51

        Эти батареи используются для стационарных устройств с длительным циклом работы. Ёмкость меньше чем у классических литий ионных, вес выше. В сети есть ролики переделки классического ИБП на литий железо. По идее если переделать то можно о обслуживании ИБП вообще забыть.


    1. dephonica
      16.07.2023 20:51

      CTECHi GT200 и старше или аналоги. Пользуюсь таким, запитан от мелкой солнечной панели, заряжает гаджеты. Если запитать от сети, то может в on-line режиме тянуть разнообразные (12V, USB QC/PD, 220 вольт синус) нагрузки до 60 (120) ватт.


      1. buldo
        16.07.2023 20:51

        То есть его можно считать полноценным UPS? Он точно подходит для работы 24/7?


        1. dephonica
          16.07.2023 20:51

          Здесь у меня статистики нет. Схемотехника в нём обычная для китайских устройств среднего уровня - стандартные DC-DC преобразователи и контроллеры USB. Если не использовать преобразователь DC/AC с его активным охлаждением, то не вижу причин, почему устройство не может работать 24/7.


    1. p0isk
      16.07.2023 20:51
      +2

      Можете посмотреть, что китайцы предлагают:

      https://docs.google.com/spreadsheets/d/1WIIdczQSsjFlOcGYJvY7Nui4Ds2VxIuO/


    1. N1Tron1X
      16.07.2023 20:51

      Насколько такая идея в принципе реальна? Ячейка lifepo4 в заряженном состоянии выдаёт 3.65 В, т.е. 4 ячейки - 14.6 В. Оборудование скорее всего не будет против такого напряжения, я вот мозги какого-то ИБП - вполне. Есть высокая вероятность получить постоянно недозаряженные АКБ.

      Лично я собрал бы такой сэтап:

      1. Блок переключения питания с зарядным устройством

        https://tahion.spb.ru/product/blok-pereklyucheniya-pitaniya-s-zaryadnym-ustrojstvom-bpzu-12/

      2. Аккумуляторная батарея Delta HR 12-7.2 (12V / 7.2Ah)

        https://www.delta-battery.ru/catalog/hr/delta-hr-12-7.2/

      Ёмкость АКБ под свои нужды и кошелёк, в качестве ИБП можно найти решение под любой бюджет- дороже UPS от mini-box.com , дешевле - не имею опыта использования, советовать не буду


      1. buldo
        16.07.2023 20:51

        Какая разница, какое напряжение ячейки? DC/DC преобразователи же не просто так существуют.

        Так-то есть батареи lifepo4 в форм-факторе свинцовых - внутри ячейки и схемы заряда и защиты.


  1. Harwest
    16.07.2023 20:51

    Raspberry Pi4 с установленным на нем умным домом, если вдруг он зависнет.

    Улыбнуло про 'зависнет'.

    Года три назад отказался от малинок совсем и навсегда в пользу нормальных одноплатников с еММС/SSD. Сейчас рабочий комплект работает на x64 аппарате Aaeon Up Squared, на нем же поднят LTE роутер плюс локальный файрвол плюс dnsmasq. Резервный инстанс- на Banana pi M5 4/32. Оба одноплатника тянут LMS media server c несколькими сетевыми плеерами.


    1. foxyrus Автор
      16.07.2023 20:51

      Отлично работает, HA установлен на внешнем SSD. Для сетевого плеера есть NAS.


  1. randomsimplenumber
    16.07.2023 20:51
    +1

    Подумалось. Мозги умного дома под бесперебойником. - это хорошо, да. И роутер тоже хорошо. Но в доме нет света, не работает котел, холодильник, комп, насос.. Чего то в этом решении не хватает.


    1. foxyrus Автор
      16.07.2023 20:51
      +1

      У меня "перерывы света" 1-5 секундные (редко до 30 минут), но вот после такого перерыва что навороченный роутер, что умный дом "поднимаются" несколько минут.


      1. randomsimplenumber
        16.07.2023 20:51

        Если поднимается автоматически, не вижу проблемы. Ну + лишних несколько минут без интернета.


        1. olartamonov
          16.07.2023 20:51
          +1

          Угу. Например, в середине вебинара или делового разговора.


          1. SpiderEkb
            16.07.2023 20:51

            Тогда инет тоже резревировать надо.

            Основной канал оптика + горячий резерв LTE с направленной на вышку внешней антенной. И роутер сам должен уметь переключаться туда-сюда.


    1. SpiderEkb
      16.07.2023 20:51
      +1

      Это уже совсем другого порядка вещи. Написал выше. Там нужен нормальный мощный инвертор 3-5 КВА, с чистым синусом на входе и достаточное количество батарей (исходя из того, сколько по времени нужно поддерживать "хозяйство" и какова его суммарная мощность).

      Все это для дома - да. Для квартиры может быть избыточно. И габариты там не для полочки в кладовке.

      Ну и цены будут от 50тр начинаться...