Как-то надо было сделать автоматическое освещение на лестнице на даче, чтобы ночью по пути не свернуть шею ненароком. Понятно, что датчик движения есть и был поставлен в нужном месте. А вот самоделки с управлением монтировать в ночник на стене не хотелось. Ну и решил я взять ZigBee лампочки с Е14 цоколем. Что может пойти не так с готовым решением?
Китаец, впрочем, понял меня не так и прислал мне WiFi лампочки с E14 цоколем, Philips. Цепляются они к инфраструктуре Xiaomi через Mi Home. Для особо красноглазых (вроде меня) можно выдернуть токен и подключить к Home Assistant. Собственно, так я и сделал. Но вот работали эти лампы через пень колоду. Тормозили на включение, эпизодически теряли сеть и их нужно было выключать и включать. Если им разрешить доступ к оригинальному облаку Xiaomi — лучше не становилось. Проблемы были не настолько критичными, чтобы менять лампу, и они проработали у меня больше года. Но недавно наткнувшись на эту проблему ночью, я понял, что терпение мое кончилось и пора исправлять ситуацию подручными средствами. О том, как их перепрошить, я и решил сделать пост в бложике.
По сути, все было сделано до меня. Фанаты Tasmota уже развинтили эти лампы и описали, как подключать UART. А не менее ярые фанаты esphome сделали конфиг для последнего.
Когда я понял, что «по воздуху» в esphome эти лампы не прошить и придется разбирать их, я столкнулся с двумя проблемами:
- Не нашлось инструкции, как разобрать лампу, не превратив ее в процессе в кучу обломков (как здесь).
- Имеющийся конфиг для esphome не имел нескольких нужных для меня фичей, и не выключал «холодный белый» при выключении лампы с кнопки в интерфейсе.
Потому я включил паяльник, взял отвертку и взялся за работу — исправлять две свеженайденные проблемы.
Сборка-разборка
Нам потребуется канцелярский нож, пара шлицевых отверток разного размера и немного удачи. Конструкция явно не предусматривает обслуживание.
Для начала вгоняем канцелярский нож под прозрачную линзу и обводим. Одна из моих ламп была просто на защелках, на одной были следы клея. Проходимся по кругу чтобы снять клей и выбираем место куда будет проще вогнать отвертку.
Вгоняем для начала маленькую отвертку и готовим плацдарм для большой.
А потом вгоняем большую и повернув ее немного на бок снимаем пластиковую линзу. Действуем аккуратно — нам еще это потом надо собрать.
Видим примерно такую картину. Нам надо снять припой. Можно использовать отвертку, или оловоотсос. Я использовал последний.
Прогреваем агрегат и убираем припой.
Немного припоя может остаться, как на фотографии ниже. Надо убедится что мы его сняли полностью.
Теперь мы можем вытащить металлическую вставку. Аккуратно подцепляем ее отверткой и проходимся по кругу. Она сидит очень плотно, потому с ней придется немного помучаться.
Победа. Вставка снята и мы получаем доступ к электронике.
Помните анекдот, что собирать «корабли в бутылках» — это работа для проктологов в отставке? Вот нас ждет примерно такая же задача, потому как электроника залита эпоксидкой внутри пластика.
По опыту, удобнее капнуть капельки припоя на тестовые пады, к которым мы будем паяться. А нам нужны: RX, TX, GND, VCC и IO0. Спасибо китайцам — они подписаны на шелкографии!
На VCC подаем 3.3 вольта, IO0 кидаем на землю.
Пациент вскрыт и мы можем удалить из него всю облачную ересь от вендора и прошить штатными средствами в esphome или tasmota. Это надо сделать только один раз, так как дальнейшие обновления мы уже сможем делать «по воздуху».
Конфиги для esphome
Конфиг для esphome изначально придумал @Sergey-SRG. Его потом форкнул и доработал @syssi. В его же репозитории оно собирается под самой последней версией esphome. Но с ним у меня не отключался до конца «холодный белый» при выключении лампы. Пришлось немного доработать напильником. Код я закинул в свой форк и отправил Pull Request.
Бонус: Термодатчик
Сумрачные китайские гении впендюрили на лампочку небольшую RTOS. Да, операционную систему на долбаную лампочку! (Читать голосом Володарского). И у нее еще даже есть интерактивная консоль на UART’е, которую и нашли фанаты tasmota. Процитирую их тут:
help
reboot
restore
setwifi ARG: <"ssid"> <"passwd"> RET: ok/ error
getwifi ARG: none RET: <"ssid"> / error
gettemp ARG: get temperature data
stop_mcmd ARG: stop miio cmd RET: none
model ARG: <model_string> RET:
getversion ARG: get firmware version
getheap ARG: get heap: ok/error
mac ARG: none RET: ok/error
bri ARG: bright pwm test, 0-100 RET: ok/error
cct ARG: cct pwm test, 0-100 RET: ok/error
setcct ARG: cct control test, 0-100 RET: ok/error
setbri ARG: bri control test, 0-100 RET: ok/error
setbricct ARG: bri and cct control test, 0-100 RET: ok/error
applyscene ARG: apply scene: ok/error
Мой взгляд сразу уцепился за gettemp ARG: get temperature data. На месте китайца я бы впендюрил термистор на единственную ногу АЦП ESP8266, чтобы знать не расплавилась ли лампа в цоколе, когда летом будет жарко. Поэтому я добавил в конфиг опрос АЦП и ожидаемо напряжение на этой ноге менялось в зависимости от температуры. К сожелению, чтобы узнать точно схему подключения, номинал резистора и прочее — надо раздербанить лампу, чего делать не хотелось. Пользуясь методом научного тыка я установил сопротивление в делителе напряжения в 500к, коэффицент взял такой же, как в термодатчиках для 3д-принтера, а сопротивление NTC — 100k. Откалибровал лампу «на ощупь», и понаблюдал, как она прогревается на максимальной яркости с 30 до 40 градусов. А после поставил костыль, который снижает плавно яркость, когда температура превышает 55 градусов.
light: - platform: custom lambda: |- auto light_out = new XiaomiLight(id(out_cw),id(out_b)); App.register_component(light_out); return {light_out}; lights: - name: $hostname Light id: TheLight gamma_correct: 0 sensor: - platform: ntc id: the_ntc sensor: resistance_sensor calibration: b_constant: 3950 reference_temperature: 25°C reference_resistance: 100000 name: "$hostname NTC Temperature" on_value: if: condition: light.is_on: TheLight then: lambda: |- float brt; id(TheLight).current_values_as_brightness(&brt); if (x > 55) { brt -= 0.1; auto cl = id(TheLight).turn_on(); cl.set_brightness(brt); cl.perform(); ESP_LOGD("NTC", "Overheat! Decreasing brightness to %f", brt); } - platform: resistance id: resistance_sensor sensor: source_sensor configuration: DOWNSTREAM resistor: 500000 reference_voltage: 3.3 name: $hostname Resistance Sensor internal: true - platform: adc name: "$hostname RAW ADC" internal: true id: source_sensor pin: A0 update_interval: 60s filters: - median: window_size: 3 send_every: 1 send_first_at: 1
Если кому доводилось окончательно раздербанивать эти лампы, пожалуйста дайте знать и поделитесь фотками. Так можно будет вбить реальный номинал резистора и получить более адекватные результаты считывания температуры.
Итого
После хирургического вмешательства пациент пошел на поправку. Отвалы от сети прекратились, стабильность работы повысилась, реагировать на команды лампы стали быстро. Острая потребность в китайском облаке, Mi Home и «Mainland China» в настройках региона Mi Home тоже бесследно пропали.