Реалізація управління сонячними панелями через мобільний додаток
Сонячна система — це не просто панелі. Це комбінація: панелі → інвертор → акумуляторний блок (опціонально) → точка підключення до мережі. Мобільний додаток управляє не панелями напрямку, а інвертором і системою управління накопичувачем. Кожен виробник інверторів — Huawei FusionSolar, SolarEdge, Fronius, SMA, GoodWe — має свій API або протокол. Уніфікованого стандарту немає.
Протоколи інверторів
| Виробник | Локальний протокол | Облачний API |
|---|---|---|
| Huawei FusionSolar | Modbus TCP + SUN2000 SDK | FusionSolar OpenAPI |
| SolarEdge | Modbus TCP | SolarEdge Monitoring API |
| Fronius | REST (Fronius Solar API v1) | Fronius Solar.web API |
| SMA | SMA Data Manager Modbus | Sunny Portal REST |
| GoodWe | Modbus TCP | GoodWe SEMS API |
| Enphase | N/A | Enlighten API v4 |
Для більшості невеликих систем використовується облачний API виробника — простіше, не вимагає відкриття портів у локальній мережі. Для промислових інсталяцій та офлайн-роботи — локальний Modbus TCP.
Huawei FusionSolar OpenAPI
Один з популярних інверторів у Європі та СНГ. API вимагає авторизації через HTTPS Basic + systemCode:
// iOS
struct FusionSolarClient {
let baseURL = URL(string: "https://intl.fusionsolar.huawei.com/thirdData")!
var token: String?
mutating func login(userName: String, systemCode: String) async throws {
let body = ["userName": userName, "systemCode": systemCode]
let response: LoginResponse = try await post("/login", body: body)
token = response.data.token
}
func getStationList() async throws -> [Station] {
let response: StationListResponse = try await post(
"/getStationList",
body: ["pageNo": 1]
)
return response.data.list
}
func getRealTimeData(stationCode: String) async throws -> RealTimeData {
return try await post("/getStationRealKpi", body: ["stationCodes": stationCode])
}
}
Основні показники з getStationRealKpi: radiation_intensity (інсоляція), theory_power (теоретична потужність), inverter_power (реальна генерація), power_profit (вироблення кВт·ч за день), use_power (спживання).
Fronius Solar API: локальний REST
Fronius інвертори надають REST API прямо з інвертора без облака:
GET http://192.168.1.20/solar_api/v1/GetPowerFlowRealtimeData.fcgi
Відповідь:
{
"Body": {
"Data": {
"Site": {
"Mode": "produce-load-grid",
"P_Grid": -1250.5,
"P_Load": -2800.0,
"P_PV": 4050.5,
"P_Akku": null,
"E_Day": 18.4,
"E_Year": 4230.0
}
}
}
}
P_Grid — від'ємне значення означає подачу в мережу. P_Load — спживання дому. P_PV — поточна генерація. Різниця видна одразу: 4050 Вт генерується, 2800 Вт спживається, 1250 Вт віддається в мережу.
Fronius API опитується напрямку з додатка тільки в межах локальної мережі. Для віддаленого доступу — через зворотний прокси з авторизацією або через Fronius Solar.web API.
Дашборд: візуалізація потоків енергії
Ключовий екран — діаграма потоків енергії: панелі → дім → мережа → акумулятор. Анімовані стрілки показують напрямок потоку. На Flutter:
class EnergyFlowPainter extends CustomPainter {
final double pvPower; // генерація
final double gridPower; // <0 в мережу, >0 з мережи
final double loadPower; // спживання
final double batteryPower; // <0 заряд, >0 розряд
@override
void paint(Canvas canvas, Size size) {
_drawNode(canvas, pvIcon, pvPosition, '$pvPower Вт');
_drawNode(canvas, homeIcon, homePosition, '$loadPower Вт');
_drawNode(canvas, gridIcon, gridPosition, '${gridPower.abs()} Вт');
if (pvPower > 0) {
_drawAnimatedArrow(canvas, pvPosition, homePosition,
color: Colors.green, active: true);
}
if (gridPower < 0) {
_drawAnimatedArrow(canvas, homePosition, gridPosition,
color: Colors.orange, active: true);
}
}
}
Управління: режими роботи інвертора
SolarEdge та Huawei дозволяють переключати режими через API: Self-Consumption (максимум на свої потреби), Time-of-Use (заряджати акумулятор за нічним тарифом), Export Limitation (обмеження подачі в мережу до заданого значення).
Команда через SolarEdge API:
suspend fun setStorageCommand(siteId: String, command: StorageCommand): Result<Unit> {
return withContext(Dispatchers.IO) {
runCatching {
val response = api.setStorageCommand(
siteId = siteId,
body = StorageCommandBody(
mode = command.mode.apiValue,
chargeLimit = command.chargeLimit,
dischargeLimit = command.dischargeLimit,
)
)
if (!response.isSuccessful) {
throw ApiException(response.code(), response.message())
}
}
}
}
Зміна налаштувань інвертора — операція з наслідками. UX повинен вимагати явного підтвердження та показувати поточний режим окремо від команди, яка очікує застосування.
Розробка мобільного додатка для моніторингу однієї сонячної системи через облачний API: 2-3 тижні. Підтримка кількох інверторів, локальний Modbus TCP, управління режимами та автоматизація: 5-8 тижнів. Вартість розраховується після уточнення обладнання.







