Налаштування Deye з комп'ютера: змінюємо струм заряду і графік через Modbus
Deye: режими, помилки, локальний доступ
Оновлено:
Налаштування гібридного Deye зазвичай міняють на екрані інвертора або в застосунку. Але вони лежать у регістрах Modbus, а значить, їх можна читати й змінювати скриптом, по локальній мережі, без хмари. Ми перевірили це на власному однофазному Deye: прочитали налаштування, змінили три параметри, прочитали ще раз, повернули назад. Нижче все, що вийшло, з реальним виводом скрипта.
Що перевірено. Експеримент зроблено 14 жовтня 2026 на однофазному гібридному Deye зі старим WiFi-логером (порт 8899, протокол Solarman V5). Адреси регістрів взяті з визначення ha-solarman для Deye hybrid, і для описаних нижче регістрів ми підтвердили читання й запис на цьому інверторі. На трифазних моделях і новому логері (прошивка 1.7.x, порт 502) адреси можуть відрізнятися. Спершу прочитайте, потім міняйте.
Що для цього потрібно
- Інвертор Deye з WiFi-логером у вашій домашній мережі.
- Локальний доступ до логера. Якщо його немає, спершу прочитайте як повернути локальний доступ через Modbus TCP.
- IP-адреса логера і серійник самого логера. Серійник інвертора не підходить.
- Python 3 і бібліотека
pysolarmanv5(для порту 8899). Для порту 502 підійде звичайний клієнт Modbus TCP.
python3 -m venv venv
./venv/bin/pip install pysolarmanv5
Підключення і перші граблі
from pysolarmanv5 import PySolarmanV5
m = PySolarmanV5("192.168.1.44", 1234567890, port=8899, mb_slave_id=1)
print(m.read_holding_registers(210, 2)) # [80, 90]
З нашого досвіду, три речі, на які можна впертись:
- Порт 502 закритий, 8899 відкритий. Це нормально для старих логерів: вони говорять не чистим Modbus TCP, а обгорткою Solarman V5. Бібліотека
pysolarmanv5це знає. - Помилка «incorrect data logger serial number». Ми спершу ввели серійник інвертора, а не логера. Логер у відповіді повертає свій серійник, його можна прочитати з байтів 7–10 відповіді (little-endian), або просто знайти на сторінці Status логера й на наклейці.
- Запис функцією 6 не спрацював. Команда
write_holding_registerповернула Modbus-виняток 5 (Acknowledge), значення не змінилося. Той самий запис через функцію 16,write_multiple_holding_registers(адреса, [значення]), пройшов. Якщо у вас те саме, пробуйте FC16.
Регістри, які ми перевірили
Усі значення цілі, 16-бітні.
| Що | Регістр | Як читати | У нашому інверторі |
|---|---|---|---|
| Макс. струм заряду акумулятора | 210 | амперів | 80 |
| Макс. струм розряду | 211 | амперів | 90 |
| Time of Use (дні тижня) | 248 | бітова маска днів, 255 = щодня | 255 |
| Час початку програм 1–6 | 250–255 | ГГХХ, 2305 = 23:05 |
23:05, 00:00, 06:55, 15:00, 17:00, 21:00 |
| Потужність програм 1–6 | 256–261 | ват | 6000 |
| Цільовий SOC програм 1–6 | 268–273 | відсотків | 50, 50, 50, 60, 60, 50 |
| Заряд від мережі програм 1–6 | 274–279 | бітове поле | 5, 5, 4, 4, 4, 4 |
Як це працює: добу поділено на шість програм, кожна діє від свого часу до початку наступної. У кожної програми є потужність, цільовий SOC і прапорці. Це ті самі налаштування, що ви бачите на екрані інвертора в розділі Time of Use.
Бітове поле заряду від мережі, за визначенням ha-solarman: біт 0 вмикає заряд від мережі, біт 1 від генератора. У нашому інверторі значення 5 і 4 означають, що біт 2 теж виставлено. Його призначення ми не з'ясовували, тому не чіпали. Саме тому змінювати треба лише потрібний біт, а не записувати число «з голови».
Експеримент: читаємо, міняємо, читаємо, повертаємо
Скрипт спершу читає все й зберігає копію у файл. Потім для кожного параметра по черзі записує нове значення, одразу читає його назад, повертає початкове і знову читає. Наприкінці порівнює стан із початковим.
Початковий стан:
{
"max_charge_current_A (210)": 80,
"max_discharge_current_A (211)": 90,
"time_of_use (248)": 255,
"program_time_hhmm (250-255)": [2305, 0, 655, 1500, 1700, 2100],
"program_power_W (256-261)": [6000, 6000, 6000, 6000, 6000, 6000],
"program_soc_pct (268-273)": [50, 50, 50, 60, 60, 50],
"program_charging_flags (274-279)": [5, 5, 4, 4, 4, 4]
}
Що змінювали і що прочитали одразу після запису:
| Крок | Запис | Прочитано назад |
|---|---|---|
| 1. Струм заряду | регістр 210: 80 → 70 А | 70 |
| Повернення | 210: 70 → 80 А | 80 |
| 2. SOC програми 1 | регістр 268: 50 → 55 % | 55 |
| Повернення | 268: 55 → 50 % | 50 |
| 3. Заряд від мережі, програма 1 | регістр 274: 5 → 4 (біт 0 вимкнено) | 4 |
| Повернення | 274: 4 → 5 | 5 |
Фрагмент реального виводу після кроку 1 (змінився лише один рядок):
{
"max_charge_current_A (210)": 70,
"max_discharge_current_A (211)": 90,
"program_soc_pct (268-273)": [50, 50, 50, 60, 60, 50],
"program_charging_flags (274-279)": [5, 5, 4, 4, 4, 4]
}
Після кроку 3 змінився лише перший елемент масиву:
{
"program_charging_flags (274-279)": [4, 5, 4, 4, 4, 4]
}
Підсумок скрипта: RESTORED OK: True. Усі інші регістри між кроками не змінювалися. Тобто налаштування справді можна міняти з комп'ютера, і через кілька секунд бачити нове значення там, де його читає інвертор.
Мінімальна версія запису з перевіркою:
def set_reg(m, reg, value):
m.write_multiple_holding_registers(reg, [value])
got = m.read_holding_registers(reg, 1)[0]
assert got == value, f"reg {reg}: wrote {value}, read {got}"
orig = m.read_holding_registers(210, 1)[0]
set_reg(m, 210, 70)
set_reg(m, 210, orig)
Що враховувати, щоб нічого не зламати
- Спершу читайте й зберігайте копію. Перед будь-яким записом збережіть значення в файл, щоб було куди повертатись.
- Пишіть лише в регістри, призначення яких знаєте. Невідомий регістр може бути калібруванням, захистом або мережевим кодом. Для Deye правильна відправна точка: визначення ha-solarman для вашої моделі.
- Змінюйте по одному і перечитуйте. Так одразу видно, якщо інвертор відхилив або округлив значення.
- Бітові поля міняйте масками. Читаємо, змінюємо біт, пишемо назад.
- Не пишіть у циклі. Налаштування зберігаються в енергонезалежній пам'яті інвертора, у якої обмежений ресурс записів. Записуйте змінену величину раз, а не щосекунди. Це загальна рекомендація, в експерименті ми її не вимірювали.
- Один клієнт на логер. Логери зазвичай обслуговують одне підключення одночасно. На час скрипта зупиніть інтеграцію у Home Assistant, інакше можливі таймаути.
- Не відкривайте порт в інтернет. Modbus TCP не шифрується й не має авторизації: той, хто дістанеться до порту, може змінити налаштування так само, як ми.
- Межі безпеки визначає акумулятор. Не ставте струм заряду вище за те, що дозволяє виробник батареї, і не знижуйте цільовий SOC так, щоб уночі нічого не лишилось у запасі.
- Перевіряйте час. Програма, яка діє зараз, впливає на інвертор одразу. Свій експеримент ми запускали вдень, поза вікном програми, яку змінювали.
Навіщо це на практиці
1. Нічний тариф. Якщо в програмі, що діє на початку ночі, ввімкнути заряд від мережі й підняти цільовий SOC, акумулятор підзарядиться по нижчому тарифу. Вранці скрипт прибирає заряд від мережі, і далі працює сонце. Розрахунок вигоди для вашого тарифу робіть окремо: про нічний тариф.
2. Перед плановим відключенням. За графіком відключень скрипт піднімає цільовий SOC і дозволяє заряд від мережі за кілька годин до початку. Після відновлення живлення повертає звичні значення.
3. Захист вводу. Якщо заряд акумулятора разом з іншими споживачами вибиває ввідний автомат, можна обмежити струм заряду на потрібні години. Причини вибивання докладно розібрано тут.
4. Сезонні профілі. Влітку цільовий SOC і заряд від мережі мінімальні, взимку вищі. Два файли з наборами значень і одна команда замість ручного перебирання меню на екрані.
5. Журнал змін. Якщо щось пішло не так, скрипт, який пише в лог «було → стало», швидко показує, хто і коли змінив налаштування.
Усе це можна запускати за розкладом (cron) або з Home Assistant, але почніть з ручного запуску, як у нашому експерименті.
Коротко
- Налаштування Deye лежать у регістрах Modbus і змінюються скриптом через локальну мережу, без хмари.
- На старому логері порт 8899 (Solarman V5), потрібен серійник логера, а запис працює через функцію 16.
- Ми змінили й повернули струм заряду (рег. 210), SOC програми 1 (268) і заряд від мережі (274). Підсумок перевірки:
RESTORED OK: True. - Перед записом читайте й зберігайте копію, міняйте по одному параметру, бітові поля змінюйте масками.
- Не відкривайте Modbus TCP в інтернет.
- Ця стаття про ручне керування власним скриптом на власний ризик: спершу читайте, змінюйте по одному параметру і зберігайте копію.
Читайте також
- Deye Time of Use: заряд від мережі вночі: налаштування шести програм і причини, чому заряд не йде.
- Коди помилок Deye українською: що означає F-код на екрані й коли кликати майстра.
- Home Assistant і Deye: чому датчики «unavailable»: причини та послідовна діагностика.
- Режими роботи Deye: Selling First, Zero Export to Load і to CT — який вибрати: що означає кожен режим і що вибрати.
Джерела
- ha-solarman: визначення Deye hybrid: адреси регістрів Time of Use, SOC, заряду, струму.
- pysolarmanv5: бібліотека для Solarman V5.
- Власний експеримент 14 жовтня 2026: скрипт і журнал кроків у репозиторії
docs/modbus-experiment/.