5353- ** Работа без связи с машиной** : при недоступных данных о заряде автоматизация
5454 не падает, а продолжает заряжать по запасному плану.
5555- ** Троттлинг команд** — станции, плохо переносящие частые команды, получают
56- не больше одной команды в заданный интервал.
56+ не больше одной команды каждого вида в заданный интервал.
5757- ** Аварийная дозарядка** ниже критического процента вне окна — максимальным
5858 током и с запасом над порогом, чтобы не остановиться ровно на нём.
5959- ** Режим холодной погоды** : ниже заданной температуры растяжка отключается.
6666
6767```
6868нужно_кВтч = (цель % − текущий %) / 100 × ёмкость / КПД
69- осталось_ч = до конца окна − резерв (переход через полночь учтён;
70- вне окна растяжки нет)
69+ осталось_ч = до конца окна − резерв (переход через полночь учтён)
7170ток = нужно_кВтч × 1000 / осталось_ч / (U × число фаз)
7271ток = округлить вверх до шага, зажать в [минимум, максимум]
7372```
7473
74+ Вне окна зарядка идёт по двум разным поводам, и горизонт для них разный:
75+ аварийная дозарядка спешит и берёт максимум, а «доработать начатое» после
76+ конца окна доливает мягко, чтобы не создавать пик в дневном тарифе.
77+
7578Ключевое — это замкнутая обратная связь. Если машина берёт меньше, чем задано,
7679на следующем тике процент окажется ниже плана: ` нужно_кВтч ` останется прежним,
7780а ` осталось_ч ` уменьшится, и ток вырастет. Тот же механизм компенсирует неточность
@@ -209,6 +212,20 @@ https://github.com/saippuakauppias/ha-ev-smart-charging/blob/main/blueprints/aut
209212Аналогично с геолокацией: потеря позиции запрещает старт новой сессии, но не рвёт
210213уже идущую. Это отличает «трекер замолчал» от «машина уехала».
211214
215+ ### Ручная зарядка
216+
217+ Если заполнить поле «Флаг сессии», автоматизация начнёт отличать свою зарядку
218+ от начатой вручную и ** в чужую не вмешивается вовсе** : не подбирает ток и не
219+ гасит её в конце окна. Включили сами — значит и ток выставили какой хотели.
220+ Исключение одно: при неисправности станции зарядка прекращается в любом случае.
221+
222+ Воткнутый заранее кабель при выключенной зарядке чужой сессией не считается —
223+ это обычный способ поставить машину ждать ночи, и в окне она начнёт заряжаться
224+ своим порядком.
225+
226+ Без этого флага отличить одно от другого нечем: Home Assistant не запоминает,
227+ кто щёлкнул выключателем.
228+
212229Тот же принцип применён к статусу станции. Если сенсор статуса стал нечитаемым
213230(` unknown ` / ` unavailable ` ), новая сессия ** не начинается** — отличить
214231подключённый кабель от пустой розетки нечем, а включение вслепую вдобавок
@@ -220,6 +237,7 @@ https://github.com/saippuakauppias/ha-ev-smart-charging/blob/main/blueprints/aut
220237
221238| Ситуация | Что было бы | Что делает блюпринт |
222239| ---| ---| ---|
240+ | Минимальный и максимальный ток перепутаны местами | Ток выше расчётного для проводки | Побеждает максимум: поднять потолок нельзя, опустить пол можно |
223241| В поле энергии сессии указан накопительный счётчик | «Уже залито 4500 кВт·ч» → цель считается достигнутой | Считает сенсор недоступным и заряжает по резервному плану |
224242| Сняты все галочки дней недели | Окно не откроется никогда | Трактует как «все дни» |
225243| Сенсор напряжения врёт (мВ вместо В) | Ток падает до минимума на всю ночь | Отбрасывает значения вне 175–280 В |
@@ -296,8 +314,8 @@ https://github.com/saippuakauppias/ha-ev-smart-charging/blob/main/blueprints/aut
296314
297315` ` ` bash
298316pip install -r requirements-dev.txt
299- pytest -m "not slow" # 388 тестов , около 5 секунд
300- pytest -m slow # мутационное тестирование, около 3.5 минут
317+ pytest -m "not slow" # 441 тест , около 10 секунд
318+ pytest -m slow # мутационное тестирование, около 7 минут
301319` ` `
302320
303321| Файл | Что проверяет |
@@ -312,6 +330,7 @@ pytest -m slow # мутационное тестирование, ок
312330| `test_throttle_and_alarms.py` | Троттлинг команд, зона нечувствительности, контроль исправности |
313331| `test_triggers.py` | Шаблонные триггеры, в том числе на пустом наборе сущностей |
314332| `test_night_simulation.py` | Сквозная симуляция ночи в замкнутом контуре, включая приезд и отъезд машины, неисправность, потерю связи, мороз и watchdog |
333+ | `test_actions.py` | Команды, уходящие станции : состав, порядок, троттлинг, хуки |
315334| `test_mutations.py` | Проверка самих тестов : ловят ли они намеренно сломанный блюпринт |
316335
317336Последний файл самый ценный. Он моделирует батарею и прогоняет регулятор
@@ -325,7 +344,7 @@ pytest -m slow # мутационное тестирование, ок
325344
326345Зелёный набор тестов сам по себе ничего не доказывает — тесты бывают
327346бессодержательными. `test_mutations.py` намеренно ломает блюпринт по одному месту
328- за раз (23 мутации, каждая соответствует обещанию из этого README) и убеждается,
347+ за раз (32 мутации, каждая соответствует обещанию из этого README) и убеждается,
329348что остальной набор это замечает. Выжившая мутация означает, что соответствующее
330349поведение не покрыто.
331350
0 commit comments