|
3 | 3 | Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), |
4 | 4 | версионирование — [семантическое](https://semver.org/lang/ru/). |
5 | 5 |
|
| 6 | +## [1.4.4] — 2026-08-07 |
| 7 | + |
| 8 | +Шестая ночь — первая на 1.4.3 и самая спокойная: 37 прогонов, заряд 67 → 99 % |
| 9 | +к концу окна и 100 % вскоре после. Правки 1.4.3 подтвердились: шлейф «машина |
| 10 | +не дома» после финиша исчез, журнал больше не обещает применения там, где |
| 11 | +знает только об отправке. Регулирование снова трогать не пришлось — уставка |
| 12 | +13 А продержалась с 23:30 до 05:00, и это не залипание, а зона |
| 13 | +нечувствительности, погасившая колебания плана в пределах 12.0–12.8 А. |
| 14 | + |
| 15 | +Оба исправления ниже нашлись потому, что пользователь сдвинул начало окна |
| 16 | +на 23:30. Ни одно из них к этой настройке не привязано. |
| 17 | + |
| 18 | +### Исправлено |
| 19 | + |
| 20 | +- **Два триггера, совпавшие по времени, слали одну и ту же команду дважды.** |
| 21 | + Круглое время старта попадает на сетку пересчёта: `window_start` и `tick` |
| 22 | + дали два прогона с разницей 204 мс, и оба успели дойти до `number.set_value`. |
| 23 | + Режим `restart` не спасает — первый прогон отправляет команду раньше, чем |
| 24 | + второй его вытесняет. В станцию ушли две одинаковые записи за пятую долю |
| 25 | + секунды: ровно тот интервал, от которого заведён `command_gap`, и ровно то, |
| 26 | + чего дешёвые станции не переваривают. |
| 27 | + |
| 28 | + Троттлинг этого не видел принципиально. Он считает время по возрасту |
| 29 | + сущности станции, а та за 204 мс измениться не успела: второй прогон |
| 30 | + прочитал тот же `current_age`, что и первый, и счёл паузу выдержанной. |
| 31 | + Добавлен `run_age` — возраст предыдущего прогона самой автоматизации, |
| 32 | + который берётся из `this.attributes.last_triggered`. Снимок `this` |
| 33 | + делается **до** запуска, поэтому там всегда предыдущий прогон, а не |
| 34 | + текущий. |
| 35 | + |
| 36 | + Проверено на живом Home Assistant 2026.2.3 вместе с тремя его отказами, |
| 37 | + каждый из которых обработан: `this` равен `none`, пока сущность |
| 38 | + автоматизации не создана; `last_triggered` равен `None` при первом |
| 39 | + в жизни запуске, причём ключ существует — значит `get` со значением |
| 40 | + по умолчанию не спасает, а вычитание бросает `TypeError`; атрибута может |
| 41 | + не быть вовсе. Во всех трёх случаях блюпринт отвечает «давно», и |
| 42 | + троттлинг работает как раньше — свежая установка не откажется заряжать. |
| 43 | + |
| 44 | + Проверка добавлена и отдельным множителем к `needs_write`: исключение |
| 45 | + `or not switch_on` снимает троттлинг перед стартом сессии целиком, а |
| 46 | + гонка случилась именно там, при выключенной станции. |
| 47 | + |
| 48 | +- **Блюпринт называл собственную сессию чужой прямо посреди её остановки.** |
| 49 | + Ветка остановки гасит выключатель, а следом опускает флаг сессии. Флаг — |
| 50 | + локальный `input_boolean`, он падает мгновенно; станция подтвердила |
| 51 | + выключение через 43 секунды. В этом зазоре выключатель ещё `on`, а флаг |
| 52 | + уже `off` — в точности признак ручной зарядки, и прогон 06:55:28 в него |
| 53 | + попал. |
| 54 | + |
| 55 | + В ту ночь обошлось: гасили по рапорту «заряжено», а он входит в список |
| 56 | + причин, действующих независимо от владельца. Останавливай мы по концу |
| 57 | + окна — повторная команда уже не ушла бы, потому что `must_stop` требует |
| 58 | + `not foreign_session`. Проглоти станция единственный `turn_off`, зарядка |
| 59 | + лилась бы дальше, а блюпринт до утра звал бы её чужой и не трогал: выхода |
| 60 | + из этого состояния нет, уборка флага требует выключенного выключателя. |
| 61 | + |
| 62 | + Добавлен `finishing_own_stop` — узкий признак «выключатель свежий, значит |
| 63 | + это след нашей же только что отправленной команды». Ослаблять сам |
| 64 | + `foreign_session` нельзя, и это проверено: выдержка там снимает защиту |
| 65 | + ручной зарядки в первую же секунду после обрыва связи, потому что обрыв |
| 66 | + омолаживает выключатель, и блюпринт начинает переписывать человеку его |
| 67 | + ток — ровно то, против чего флаг и заведён. |
| 68 | + |
| 69 | +- **Обрыв связи снимал щадящий финиш вместе с выключателем.** Ограничение |
| 70 | + «на последних процентах ток не поднимаем» действовало, пока выключатель |
| 71 | + включён, — а обрыв уводит его не в `off`, а в `unavailable`. В шестую ночь |
| 72 | + прогон 06:31:06 при заряде 99 % посчитал 18 А вместо разрешённых 14, и |
| 73 | + уберегло только то, что станция была офлайн и команды не слались. Оборвись |
| 74 | + один выключатель при живой станции — в почти полную батарею ушло бы 28 А, |
| 75 | + ровно то, от чего щадящий финиш и заведён. |
| 76 | + |
| 77 | + Теперь потолок снимается только при **подтверждённом** `off`, то есть |
| 78 | + перед началом новой сессии. Это то, ради чего условие и существовало: |
| 79 | + новая сессия не должна наследовать вчерашнюю уставку как потолок. |
| 80 | + |
| 81 | +### Инструменты |
| 82 | + |
| 83 | +- Отчёт по трассировкам замечает гонку триггеров: два прогона, стартовавших |
| 84 | + меньше чем за секунду друг от друга и пославших станции одну и ту же |
| 85 | + команду. Очередь «уставка → включение» гонкой не считается — это штатное |
| 86 | + разнесение команд по разным прогонам. |
| 87 | +- `ha_sim` научился `this` и заворачивает ошибки рендера в `TemplateError` |
| 88 | + так же, как это делает `Template.async_render` в Home Assistant. Прежде |
| 89 | + эмулятор пропускал наружу собственные исключения Jinja, то есть на одном |
| 90 | + и том же сломанном шаблоне сообщал не тот тип ошибки, что продакшен, — |
| 91 | + дифференциальная сверка поймала это на `this.attributes` и на арифметике |
| 92 | + с пустым `last_triggered`. |
| 93 | + |
6 | 94 | ## [1.4.3] — 2026-08-06 |
7 | 95 |
|
8 | 96 | Пятая ночь обкатки прошла штатно: 40 прогонов против 65, заряд 69 → 100 %, |
|
827 | 915 | только когда максимум не делится на дискретность (например 28 А при шаге 5 А). |
828 | 916 | Обнаружено мутационным тестированием. |
829 | 917 |
|
| 918 | +[1.4.4]: https://github.com/saippuakauppias/ha-ev-smart-charging/compare/1.4.3...1.4.4 |
830 | 919 | [1.4.3]: https://github.com/saippuakauppias/ha-ev-smart-charging/compare/1.4.2...1.4.3 |
831 | 920 | [1.4.2]: https://github.com/saippuakauppias/ha-ev-smart-charging/compare/1.4.1...1.4.2 |
832 | 921 | [1.4.1]: https://github.com/saippuakauppias/ha-ev-smart-charging/compare/1.4.0...1.4.1 |
|
0 commit comments