Делаем “устрашающе умный” (с) модуль из TOMZN TOB9-VAP. Реле всего.

2 года назад заказал “wifi-автомат” от TOMZN – TOB9-VAP. Доехало, подключил, поигрался. Работает. Даже добавил интеграцию с Tuya в Home Assistant. Модуль разобрал поисследовать, с тех пор так и лежал разобранный без дела, да и привязка к сторонним сервисам меня не особо радовала. Внутри – небольшая платка с БП, измерителем на базе BL0942 и модулем CBU на BK7231N. Уже не помню, была ли поддержка таких контроллеров в конце 2023-го года, да и опыта было поменьше, чтобы легко прошить такое:

На сейчас ESP Home обзавелся поддержкой еще ряда контроллеров, в том числе BK72**, а желание отвязать железку от внешних сервисов, собрать все обратно и поставить точку в этой теме и сподвигло заняться модулем вплотную.

По  привычке иногда называю модуль “автоматом”, хотя автоматическим выключателем в обычном понимании он не является. Да, в штатной прошивке тут есть возможность выключения по превышению тока и напряжения – потому он и зовется VAP с настраиваемым лимитом тока 1-63А. Разглядывая страницу товара и отличия с TOB9-63M понимаю, что отличия моделей должны быть уже чисто софтовыми – и это дало несколько идей, которые и реализовал. Но это было потом…

Сначала была прошивка из ESP Home.

  • Для начала – подключаем pl2303. Тут есть pinout подобного модуля и пример корректировки показаний. Шили вроде как через esphome.
  • Тут есть базовый конфиг, показ внутренностей и отсылка к утилитам прошивки.
  • Создаем прошивку в esphome, там есть BK7231N. Скачиваем первый вариант файла – *.uf2. Распаиваем 5 проводов на модуль, подключаем на pl2303. В этот раз уже делал все изначально через левел-шифтер, чтобы исключить возможные подводные камни с уровнями.
  • Описание вариантов утилит для прошивки. Рекомендуется ltchiptool, но запустить на Linux’е так и не смог (отсылка на ImportError: cannot import name ‘Endianness’ from ‘datastruct’ – и там реально такого нет). В итоге первый раз шил виндой, чтобы убедиться, что со стороны железа косяков нет и оно реально шьется (отсюда брал дрова для винды для pl2303).
  • Потом скачал bk7231tools – это работает, так что дальше пробовал шить уже в Linux’е. Ставим
    $ pip3 install bk7231tools
    потом запускаем:

    $ python3 .local/bin/bk7231tools write_flash -d /dev/ttyUSB0 -s 0 -S 0 -l 0x200000 --bootloader downloads/tomzn-switch-1.uf2
    Жмем кнопку сброса контроллера, получаем 
    BK72xx connected - protocol: FULL, chip: BK7231N, bootloader: BK7231N_1_0_1, chip ID: 0x7231c, boot version: None
    Connected! Chip info: BK7231N / Flash ID: 1c 70 15 / Flash size: 0x200000 / Protocol: FULL
    Writing 2097152 bytes to 0x0
    Trying to unprotect flash memory...
    Erasing and writing at 0x0 (0.00%)
     - Checking block pre-erase @ 0x0
     - Trying to erase block @ 0x0
     - Checking block post-erase @ 0x0
     - Erase succeeded @ 0x0
    Erasing and writing at 0x1000 (0.20%)
    Erasing and writing at 0x2000 (0.39%)
    Erasing and writing at 0x3000 (0.59%)
    Erasing and writing at 0x4000 (0.78%)
    **********
    Erasing and writing at 0x1FF000 (99.80%)
    OK!
    

    [свернуть]

    Но… я не знаю, в какой момент что-то пошло не так или где я ошибся – но модуль “окирпичился” и не грузился. Пробовал шить снова под виндой – ругалось на bootloader (1, 2), но что-то шило. Перебирал разные варианты опций, пробовал шить OpenBK. Хуже то, что у меня не осталось заводской прошивки, а в сети найти не мог. Так или иначе, но в какой-то момент все заработало. Дамп своей прошивки через bk7231tools и заливка ее потом обратно тоже дают работающее устройство. В общем, чтобы повторить все шаги снова на заводской прошивке – мне надо будет провести эксперименты на новом устройстве.
    Для истории

    rain@walkbook:~$ python3 .local/bin/bk7231tools chip_info -d /dev/ttyUSB0
    BK72xx connected - protocol: FULL, chip: BK7231N, bootloader: BK7231N_1_0_1, chip ID: 0x7231c, boot version: None
    Connected! Chip info: BK7231N / Flash ID: 1c 70 15 / Flash size: 0x200000 / Protocol: FULL
    

    [свернуть]

Еще полезные ссылки:

А дальше – пошло-поехало.

  • Реализовал сначала базовый вариант по примеру конфига выше.
  • Добавил отключаемую защиту от выхода за лимиты напряжения, тока и мощности. Почему-то простой вариант с on_value_range не заработал, поэтому пришлось описывать все чуть более сложной логикой. Устанавливать лимиты можно через веб-интерфейс, значения нижнего и верхнего порога взаимосвязаны (т.е., нельзя поставить низ выше верха).
  • Добавил отключаемый и настраиваемый таймер возврата в рабочий режим.
  • Расширил функции кнопки: кроме включения/выключения и сброса устройства – добавил переключение режима защиты (нажатие от 1 до 5 секунд) и подумал, что неплохо было бы сбрасывать еще счетчик энергии. Но чуть позже…
  • Добавил светодиодную индикацию режима. Кроме включено/выключено из базового конфига – быстрое мигание при аварии (выходе за лимиты) и медленное мигание при выдержке включения.
  • Внутренняя скорость опроса измерителя была выставлена в 0.1s для напряжения и тока, чтобы модуль реально мог от чего-то защищать. При этом в веб-интерфейсе параметры публикуются раз в 15 секунд.
  • Появились и были устранены неожиданные подводные камни.
    • Например, логика включения и выключения реле была завязана на “маркеры” аварии и таймаута включения. И выяснилось, что в момент включения и выключения устройство состояние темплейтов меняется. А дальше состояние записывается в память и в итоге получаем отсутствие сохранения состояния реле при перезагрузке.
    • Еще один косяк был связан со скоростью опроса измерителя. Похоже, в момент выключения в какую-то долю секунды он начинает отдавать “0” (или типа того) – и при включенной защите это дает выключение реле. Что опять же, приводит к отсутствию сохранения состояния.
    • Обе проблемы были решены добавлением флага перезагрузки, который взводится на ранних этапах загрузки и в начале перезагрузки, а при обычной работе сброшен. При работе с реле делается проверка состояния этого флага.
  • Самая большая работа была проделана вокруг счетчика суточной энергии.
    • Во-первых, обычный total_daily_energy не умеет сбрасываться иначе, кроме как в 0 часов 0 минут. Отсюда несколько проблем:
      • Не могу сбросить его в произвольный момент времени.
      • Что, если в 12 ночи питания не было?
    • Первое решилось добавлением своих счетчиков и шаблонов вокруг базового счетчика энергии. Если значение базового изменилось – увеличиваем значение своего. А его уже можем сбрасывать и устанавливать так и тогда, когда захотим.
    • Для второго пришлось наконец-то доделать давно задуманный к реализации для солнечных измерителей алгоритм обнаружения смены суток – там это актуально, так как в 12 ночи солнца нет и измерители обычно выключены. В целом все просто (но поначалу у меня что-то не выходило и для измерителей тему я надолго отложил) – при синхронизации (т.е., при включении  устройства прежде всего) времени сравниваем текущий день и сохраненный в памяти. Если отличается – значит, у нас новый день и можно сбросить счетчик (а в память записать новое значение дня).
  • Все перечисленное позволило добавить сброс реализованного счетчика энергии из веб-интерфейса или удержанием кнопки от 5 до 10 секунд.
  • Кроме того – что мне изначально хотелось сделать – на базе этого я добавил отключаемый ограничитель суточной энергии. Т.е., например, за сутки можем тратить на какой-нибудь нагреватель не больше 3 кВт*ч. Есть флаг сработки лимита. Возврат в рабочий режим (при сбросе или смене суток) не делал (пока? Можно, но надо тогда сохранять состояние реле до сработки лимита и немного перепахать логику).

Да! А еще измеритель может показывать направление перетока энергии, поэтому лимиты по мощности сделал как положительные, так и отрицательные. В целом, можно использовать при управлении нагрузкой для on grid-инверторов без лимитеров, чтобы не начинать отдавать энергию наружу. Судя по всему, показания между устройствами зависят в том числе от того, куда (в какой “полярности”) прицепили провода при сборке модуля, поэтому при прошивке другого (точно такого же) модуля тот может показывать не положительные (я добавил у себя в фильтры “*-1”), а отрицательные значения.

Как уже писал выше, разница с TOB9-63M должна быть чисто софтовой, так что можно набрать их, как более дешевые и сделать аналогичную переделку. На сейчас на Али можно найти их по 8$/шт. Что, кстати, дешевле, чем Sonoff POW R3.

А для Sonoff’а можно будет тоже портировать все эти наработки, так как основные принципы не меняются – только платформа и измеритель.

Конфиг для ESP Home. Пожалуй, самый объемный на сейчас для всех моих устройств – хотя местами напрашивается сокращение какими-нибудь функциями или чем-то таким.

PS: цитата в названии – с Муськи.

PS2: в базовом коде делалась обработка значений тока/мощности, потому что “измеритель что-то показывает без нагрузки”. Что-то показывает он из-за собственного потребления – электроника включена после токового трансформатора. Если надо не учитывать свое потребление, но иметь возможность работать со значениями в 2 стороны – лучше тогда делать сдвиг параметра на определенное значение, а не обнуление. Или переподключить один проводок внутри.

Добавить комментарий