Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@

## [Unreleased]

Пока пусто — планы в [ROADMAP.md](ROADMAP.md).
### Добавлено
- **Выбор порога заряда 40/50/60/70/80/100%** — команда защиты заряда `MIFS 0x10/0x02` оказалась
многоуровневой, а не бинарной (переоткрыто 2026-07-29, разбор —
[docs/12-charge-levels.md](docs/12-charge-levels.md)): пикер порога в Настройки → Батарея;
панель/меню/OSD показывают реальный выбранный %, тумблер в панели остаётся бинарным «X% ↔ 100%»;
`ChargeGuard` переармливает выбранный порог. Старые `config.json` мигрируются сами (дефолт 80 =
прежнее поведение). На моделях без granular-уровней прошивка отвергает код — выбор откатывается
с честной ошибкой, 80/100 работают всегда (XIC-4).

### Изменено
- Локальная сборка помечается версией `0.0.0-dev` (реальную версию в релизные билды подставляет CI
из тега) — самосборный билд больше не выдаёт себя за релизный.

## [0.7.0] — 2026-07-28

Expand Down
7 changes: 5 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
## Что это

**XiControl** — трей-утилита для ноутбуков Xiaomi/Redmi (Windows 10/11 x64): защита заряда
батареи (+ разовый заряд «В дорогу»), режимы производительности, OSD, переназначаемые
батареи с выбором порога (+ разовый заряд «В дорогу»), режимы производительности, OSD, переназначаемые
Mi-кнопка и «мёртвые» клавиши, авто-герцовка, запоминание яркости по питанию, «режим совы»,
тачпад и сенсорный экран вкл/выкл, виджет «Монитор», окно настроек в стиле Win11, опциональный
HTTP API для управления из локальной сети (телефон/Home Assistant). Всё управление железом —
Expand Down Expand Up @@ -215,10 +215,13 @@ WMI-событий). `Program.cs`: single-instance mutex → DI-контейне
- Тег с суффиксом через дефис (`v0.7.0-pre`) помечается pre-release и winget **не** трогает.
- Каждый push в `main` собирает скользящий pre-release под тегом `pre` — всегда свежий билд из main;
winget его не видит (слушает только `release: [released]`).
- Локальная сборка помечается версией `0.0.0-dev` (дев-дефолт в `XiControl.csproj`, суффикс виден
в AboutTab); реальную версию подставляет CI из тега: `publish -p:Version=X.Y.Z`.

## Ограничения среды

- Железо-специфично: разработка и проверка — на Xiaomi Book Pro 14 (TM2424). WMI-вызовы к прошивке
нельзя проверить без этого железа; сборку — можно всегда.
- Порог «беречь батарею» (~80%) зашит в прошивку, произвольный процент невозможен.
- Порог «беречь батарею» — дискретный набор уровней прошивки (на TM2424: 40/50/60/70/80/100%),
произвольный процент невозможен; прошивка сама валидирует набор (см. `docs/12-charge-levels.md`).
- Датчик тока батареи беззнаковый (величина, не направление) — детали в `docs/09-power-monitoring.md`.
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ current direction is shown by color (charging green / discharging orange).*

## Features

- 🔋 **Charge protection** — "battery care" (charge to ~80%) / full charge to 100%.
- 🔋 **Charge protection** — "battery care" with a selectable threshold (40/50/60/70/80%,
picked in Settings → Battery) / full charge to 100%.
- **ChargeGuard**: the firmware drops the limit after sleep and power-source changes —
the utility re-applies it automatically.
- 🧳 **"Travel" mode** — a one-off charge to 100% on top of "care 80%": the suitcase button
- 🧳 **"Travel" mode** — a one-off charge to 100% on top of battery care: the suitcase button
in the panel / a menu item. On reaching 100% — an OSD and a sound; unplugging the charger
resets the mode by itself (the next plug-in is back to 80%).
resets the mode by itself (the next plug-in is back to the threshold).
- 🔌 **Charger wattage** — when the charger is plugged in, show the connected PD adapter's
wattage (watts) in the OSD and in the Monitor. Over the charge icon — a **PSU quality badge**:
🔴 "!" if the adapter is weaker than the configured threshold (slow charging), ⚪ "?" if the
Expand All @@ -64,7 +65,7 @@ current direction is shown by color (charging green / discharging orange).*
- ⚡ **Performance modes**: Eco (hidden firmware mode) / Quiet / Auto /
Turbo / Full speed. Eco and Full speed can be removed from the UI via config.
- 🖥️ **OSD overlay** (dark card, custom icons):
- charger plug/unplug ("Charging to 80%" / "On battery" + level);
- charger plug/unplug ("Charging to X%" with the actual threshold / "On battery" + level);
- performance mode and charge limit changes;
- microphone on/off, keyboard backlight (off / 50% / 100% / auto).
- 🅼 **Mi button**:
Expand Down Expand Up @@ -186,10 +187,10 @@ Launch `XiControl.exe` (confirm the UAC prompt) — a tray icon appears.
| Click the tray icon | Quick settings panel |
| Right-click the icon | Menu: charge, "travel", owl, auto refresh rate, Monitor, mode, Settings…, exit |
| Mi button, single click | Next performance mode + OSD *(configurable)* |
| Mi button, double click | Toggle charge limit 80% ↔ 100% + OSD *(configurable)* |
| Mi button, double click | Toggle charge limit threshold ↔ 100% + OSD *(configurable)* |
| Mi button, hold ~0.5 s | Quick settings panel |
| Microphone key | Mute/unmute the system microphone + OSD |
| "Settings" key | Toggle charge limit 80% ↔ 100% + OSD *(configurable)* |
| "Settings" key | Toggle charge limit threshold ↔ 100% + OSD *(configurable)* |
| Keyboard backlight key | OSD with the level (off / 50% / 100% / auto) |

All options live in the **Settings…** window (tray menu item): tabs General (language,
Expand All @@ -209,14 +210,14 @@ moved the file), it repairs itself on launch.

### Travel mode (a one-off charge to 100%)

You usually keep "care 80%", but before a trip you want a full charge. Press the
**suitcase button** in the panel (left of the 80/100 pills) or the **"Charge for the road"**
You usually keep battery care on (say, 80%), but before a trip you want a full charge. Press the
**suitcase button** in the panel (left of the threshold/100 pills) or the **"Charge for the road"**
menu item — the utility lifts the limit once and tops up to 100%.

- On reaching **100%** — a "ready for the road" OSD and a sound (toggle
**Settings → Battery → "Ready sound"**, on by default).
- **Unplug the charger → the mode turns off by itself**; the next plug-in is back to caring at 80%.
- Manually picking the 80/100 pill also cancels the mode. With a permanent "100%" the button is
- **Unplug the charger → the mode turns off by itself**; the next plug-in is back to the care threshold.
- Manually picking the threshold/100 pill also cancels the mode. With a permanent "100%" the button is
inactive (nothing to top up).

The 80/100 pills show the **base** setting — "travel" is a temporary override on top of it
Expand Down Expand Up @@ -375,7 +376,7 @@ Routes (all with an `Authorization: Bearer <token>` header, body — JSON):
|---|---|
| `GET /status` | Mode, charge protection, "travel", owl, charge %, charging fact, watts, battery health |
| `POST /mode` `{"value":"turbo"}` | Performance mode (`eco`/`quiet`/`auto`/`turbo`/`fullspeed`) |
| `POST /care` `{"on":true}` | "Care ~80%" on/off |
| `POST /care` `{"on":true}` | Battery care on/off (the configured threshold) |
| `POST /travel` `{"on":true}` | "Travel" mode (a one-off charge to 100%) |
| `POST /owl` `{"on":true}` | "Owl mode" (stay awake) on/off |

Expand All @@ -400,9 +401,9 @@ None of this runs or spends resources while the API is off (the server simply is

## Limitations

- The "battery care" threshold is baked into the firmware — an arbitrary percentage via WMI is
impossible. On the tested model (TM2424) it's ≈80%; on other models the threshold may differ
(e.g. 70% on models serviced by MI Control).
- The "battery care" threshold is picked from a discrete set the firmware supports — an arbitrary
percentage via WMI is impossible. On the tested model (TM2424) that's 40/50/60/70/80/100%;
on other models the set may differ (the firmware validates it itself and rejects unsupported levels).
- The Fn+Mi combo is indistinguishable from a single Mi (the firmware sends identical events),
which is why short/long presses are used.
- The feature set depends on the model: firmware telemetry (fan RPM) is unsupported on the tested
Expand Down
29 changes: 15 additions & 14 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@

## Возможности

- 🔋 **Защита заряда** — «беречь батарею» (зарядка до ~80%) / полный заряд 100%.
- 🔋 **Защита заряда** — «беречь батарею» с выбираемым порогом (40/50/60/70/80%, выбор в
Настройки → Батарея) / полный заряд 100%.
- **ChargeGuard**: прошивка сбрасывает лимит после сна и переключения питания —
утилита автоматически переустанавливает его.
- 🧳 **Режим «В дорогу»** — разово зарядить до 100% поверх «беречь 80%»: кнопка-чемоданчик
- 🧳 **Режим «В дорогу»** — разово зарядить до 100% поверх «беречь батарею»: кнопка-чемоданчик
в панели / пункт меню. По достижении 100% — OSD и звуковой сигнал; при отключении зарядника
режим сам сбрасывается (следующее подключение снова 80%).
режим сам сбрасывается (следующее подключение снова порог).
- 🔌 **Мощность зарядника** — при подключении зарядки показываем мощность подключённого
PD-адаптера (ватты) в OSD и в «Мониторе». Поверх иконки заряда — **бейдж качества блока**:
🔴 «!» если адаптер слабее заданного порога (медленный заряд), ⚪ «?» если блок не-PD (например
Expand All @@ -65,7 +66,7 @@
- ⚡ **Режимы производительности**: Эко (скрытый режим прошивки) / Тихий / Авто /
Турбо / Полная мощность. Эко и Полную мощность можно убрать из UI через конфиг.
- 🖥️ **OSD-оверлей** (тёмная карточка, авторские иконки):
- подключение/отключение зарядки («Зарядка до 80%» / «Работа от батареи» + уровень);
- подключение/отключение зарядки («Зарядка до X%» с реальным порогом / «Работа от батареи» + уровень);
- смена режима производительности и лимита заряда;
- микрофон вкл/выкл, подсветка клавиатуры (выкл / 50% / 100% / авто).
- 🅼 **Mi-кнопка**:
Expand Down Expand Up @@ -189,10 +190,10 @@ dotnet publish src/XiControl.csproj -c Release -r win-x64 --self-contained -p:Pu
| Клик по значку в трее | Панель быстрых настроек |
| Правый клик по значку | Меню: заряд, «В дорогу», сова, авто-герцовка, «Монитор», режим, «Настройки…», выход |
| Mi-кнопка, одинарный клик | Следующий режим производительности + OSD *(настраивается)* |
| Mi-кнопка, двойной клик | Переключение лимита заряда 80% ↔ 100% + OSD *(настраивается)* |
| Mi-кнопка, двойной клик | Переключение лимита заряда порог ↔ 100% + OSD *(настраивается)* |
| Mi-кнопка, удержание ~0.5 с | Панель быстрых настроек |
| Клавиша микрофона | Мьют/анмьют системного микрофона + OSD |
| Клавиша «настройки» | Переключение лимита заряда 80% ↔ 100% + OSD *(настраивается)* |
| Клавиша «настройки» | Переключение лимита заряда порог ↔ 100% + OSD *(настраивается)* |
| Клавиша подсветки клавиатуры | OSD с уровнем (выкл / 50% / 100% / авто) |

Все опции собраны в окне **«Настройки…»** (пункт меню трея): вкладки Общие (язык,
Expand All @@ -212,14 +213,14 @@ dotnet publish src/XiControl.csproj -c Release -r win-x64 --self-contained -p:Pu

### Режим «В дорогу» (разовый заряд до 100%)

Обычно держишь «беречь 80%», но перед поездкой хочется полный заряд. Нажми
**кнопку-чемоданчик** в панели (слева от пилюль 80/100) или пункт **«Зарядить „в дорогу"»**
Обычно держишь «беречь батарею» (скажем, 80%), но перед поездкой хочется полный заряд. Нажми
**кнопку-чемоданчик** в панели (слева от пилюль «порог/100») или пункт **«Зарядить „в дорогу"»**
в меню — утилита разово снимет ограничение и дозарядит до 100%.

- По достижении **100%** — OSD «можно в дорогу» и звуковой сигнал (переключатель
**Настройки → Батарея → «Звук готовности»**, по умолчанию вкл).
- **Отключил зарядник → режим сам выключается**; следующее подключение снова бережёт 80%.
- Ручной выбор пилюли 80/100 тоже отменяет режим. При постоянном «100%» кнопка неактивна
- **Отключил зарядник → режим сам выключается**; следующее подключение снова бережёт до порога.
- Ручной выбор пилюли «порог/100» тоже отменяет режим. При постоянном «100%» кнопка неактивна
(дозаряжать некуда).

Пилюли 80/100 показывают **базовую** настройку — «В дорогу» это временный оверрайд поверх неё
Expand Down Expand Up @@ -377,7 +378,7 @@ dotnet publish src/XiControl.csproj -c Release -r win-x64 --self-contained -p:Pu
|---|---|
| `GET /status` | Режим, защита заряда, «В дорогу», сова, % заряда, факт зарядки, ватты, здоровье батареи |
| `POST /mode` `{"value":"turbo"}` | Режим производительности (`eco`/`quiet`/`auto`/`turbo`/`fullspeed`) |
| `POST /care` `{"on":true}` | «Беречь ~80%» вкл/выкл |
| `POST /care` `{"on":true}` | «Беречь батарею» вкл/выкл (настроенный порог) |
| `POST /travel` `{"on":true}` | Режим «В дорогу» (разовый заряд до 100%) |
| `POST /owl` `{"on":true}` | «Режим совы» (не спать) вкл/выкл |

Expand All @@ -401,9 +402,9 @@ curl -X POST http://192.168.1.50:58125/travel \

## Ограничения

- Порог «беречь батарею» зашит в прошивку — произвольный процент через WMI невозможен.
На проверенной модели (TM2424) это ≈80%; на других моделях порог может отличаться
(например, 70% на моделях, которые обслуживал MI Control).
- Порог «беречь батарею» выбирается из дискретного набора прошивки — произвольный процент
через WMI невозможен. На проверенной модели (TM2424) это 40/50/60/70/80/100%; на других
моделях набор может отличаться (прошивка сама валидирует его и отвергает неподдержанные уровни).
- Комбинация Fn+Mi не отличима от одиночной Mi (прошивка шлёт одинаковые события),
поэтому используется короткое/длинное нажатие.
- Набор функций зависит от модели: прошивочная телеметрия (обороты вентиляторов) на проверенной
Expand Down
Loading
Loading