// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2022-2024 Thomas Basler and others */ #include "WebApi_power.h" #include "WebApi.h" #include "WebApi_errors.h" #include #include void WebApiPowerClass::init(AsyncWebServer& server, Scheduler& scheduler) { using std::placeholders::_1; server.on("/api/power/status", HTTP_GET, std::bind(&WebApiPowerClass::onPowerStatus, this, _1)); server.on("/api/power/config", HTTP_POST, std::bind(&WebApiPowerClass::onPowerPost, this, _1)); } void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request) { if (!WebApi.checkCredentialsReadonly(request)) { return; } AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { auto inv = Hoymiles.getInverterByPos(i); LastCommandSuccess status = inv->PowerCommand()->getLastPowerCommandSuccess(); String limitStatus = "Unknown"; if (status == LastCommandSuccess::CMD_OK) { limitStatus = "Ok"; } else if (status == LastCommandSuccess::CMD_NOK) { limitStatus = "Failure"; } else if (status == LastCommandSuccess::CMD_PENDING) { limitStatus = "Pending"; } root[inv->serialString()]["power_set_status"] = limitStatus; } response->setLength(); request->send(response); } void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) { if (!WebApi.checkCredentials(request)) { return; } AsyncJsonResponse* response = new AsyncJsonResponse(); JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } auto& retMsg = response->getRoot(); if (!(root.containsKey("serial") && (root.containsKey("power") || root.containsKey("restart")))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; response->setLength(); request->send(response); return; } // Interpret the string as a hex value and convert it to uint64_t const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::PowerSerialZero; response->setLength(); request->send(response); return; } auto inv = Hoymiles.getInverterBySerial(serial); if (inv == nullptr) { retMsg["message"] = "Invalid inverter specified!"; retMsg["code"] = WebApiError::PowerInvalidInverter; response->setLength(); request->send(response); return; } if (root.containsKey("power")) { uint16_t power = root["power"].as(); inv->sendPowerControlRequest(power); } else { if (root["restart"].as()) { inv->sendRestartControlRequest(); } } retMsg["type"] = "success"; retMsg["message"] = "Settings saved!"; retMsg["code"] = WebApiError::GenericSuccess; response->setLength(); request->send(response); }