-
-
Notifications
You must be signed in to change notification settings - Fork 511
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: First very basic support to read the grid profile
The parser is still missing and requires community support to collect data.
- Loading branch information
Showing
20 changed files
with
379 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
#pragma once | ||
|
||
#include <ESPAsyncWebServer.h> | ||
|
||
class WebApiGridProfileClass { | ||
public: | ||
void init(AsyncWebServer* server); | ||
void loop(); | ||
|
||
private: | ||
void onGridProfileStatus(AsyncWebServerRequest* request); | ||
|
||
AsyncWebServer* _server; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Copyright (C) 2022 Thomas Basler and others | ||
*/ | ||
#include "GridOnProFilePara.h" | ||
#include "Hoymiles.h" | ||
#include "inverters/InverterAbstract.h" | ||
|
||
GridOnProFilePara::GridOnProFilePara(uint64_t target_address, uint64_t router_address, time_t time) | ||
: MultiDataCommand(target_address, router_address) | ||
{ | ||
setTime(time); | ||
setDataType(0x02); | ||
setTimeout(500); | ||
} | ||
|
||
String GridOnProFilePara::getCommandName() | ||
{ | ||
return "GridOnProFilePara"; | ||
} | ||
|
||
bool GridOnProFilePara::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) | ||
{ | ||
// Check CRC of whole payload | ||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) { | ||
return false; | ||
} | ||
|
||
// Move all fragments into target buffer | ||
uint8_t offs = 0; | ||
inverter->GridProfile()->beginAppendFragment(); | ||
inverter->GridProfile()->clearBuffer(); | ||
for (uint8_t i = 0; i < max_fragment_id; i++) { | ||
inverter->GridProfile()->appendFragment(offs, fragment[i].fragment, fragment[i].len); | ||
offs += (fragment[i].len); | ||
} | ||
inverter->GridProfile()->endAppendFragment(); | ||
inverter->GridProfile()->setLastUpdate(millis()); | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
#pragma once | ||
|
||
#include "MultiDataCommand.h" | ||
|
||
class GridOnProFilePara : public MultiDataCommand { | ||
public: | ||
explicit GridOnProFilePara(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0); | ||
|
||
virtual String getCommandName(); | ||
|
||
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Copyright (C) 2022 Thomas Basler and others | ||
*/ | ||
#include "GridProfileParser.h" | ||
#include "../Hoymiles.h" | ||
#include <cstring> | ||
|
||
#define HOY_SEMAPHORE_TAKE() \ | ||
do { \ | ||
} while (xSemaphoreTake(_xSemaphore, portMAX_DELAY) != pdPASS) | ||
#define HOY_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore) | ||
|
||
GridProfileParser::GridProfileParser() | ||
: Parser() | ||
{ | ||
_xSemaphore = xSemaphoreCreateMutex(); | ||
HOY_SEMAPHORE_GIVE(); // release before first use | ||
clearBuffer(); | ||
} | ||
|
||
void GridProfileParser::clearBuffer() | ||
{ | ||
memset(_payloadGridProfile, 0, GRID_PROFILE_SIZE); | ||
_gridProfileLength = 0; | ||
} | ||
|
||
void GridProfileParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len) | ||
{ | ||
if (offset + len > GRID_PROFILE_SIZE) { | ||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) grid profile packet too large for buffer\r\n", __FILE__, __LINE__); | ||
return; | ||
} | ||
memcpy(&_payloadGridProfile[offset], payload, len); | ||
_gridProfileLength += len; | ||
} | ||
|
||
void GridProfileParser::beginAppendFragment() | ||
{ | ||
HOY_SEMAPHORE_TAKE(); | ||
} | ||
|
||
void GridProfileParser::endAppendFragment() | ||
{ | ||
HOY_SEMAPHORE_GIVE(); | ||
} | ||
|
||
std::vector<uint8_t> GridProfileParser::getRawData() | ||
{ | ||
std::vector<uint8_t> ret; | ||
HOY_SEMAPHORE_TAKE(); | ||
for (uint8_t i = 0; i < GRID_PROFILE_SIZE; i++) { | ||
ret.push_back(_payloadGridProfile[i]); | ||
} | ||
HOY_SEMAPHORE_GIVE(); | ||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
#pragma once | ||
#include "Parser.h" | ||
#include <Arduino.h> | ||
|
||
#define GRID_PROFILE_SIZE 141 | ||
|
||
class GridProfileParser : public Parser { | ||
public: | ||
GridProfileParser(); | ||
void clearBuffer(); | ||
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len); | ||
|
||
void beginAppendFragment(); | ||
void endAppendFragment(); | ||
|
||
std::vector<uint8_t> getRawData(); | ||
|
||
private: | ||
uint8_t _payloadGridProfile[GRID_PROFILE_SIZE] = {}; | ||
uint8_t _gridProfileLength = 0; | ||
|
||
SemaphoreHandle_t _xSemaphore; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Copyright (C) 2022 Thomas Basler and others | ||
*/ | ||
#include "WebApi_gridprofile.h" | ||
#include "WebApi.h" | ||
#include <AsyncJson.h> | ||
#include <Hoymiles.h> | ||
|
||
void WebApiGridProfileClass::init(AsyncWebServer* server) | ||
{ | ||
using std::placeholders::_1; | ||
|
||
_server = server; | ||
|
||
_server->on("/api/gridprofile/status", HTTP_GET, std::bind(&WebApiGridProfileClass::onGridProfileStatus, this, _1)); | ||
} | ||
|
||
void WebApiGridProfileClass::loop() | ||
{ | ||
} | ||
|
||
void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request) | ||
{ | ||
if (!WebApi.checkCredentialsReadonly(request)) { | ||
return; | ||
} | ||
|
||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096); | ||
JsonObject root = response->getRoot(); | ||
|
||
uint64_t serial = 0; | ||
if (request->hasParam("inv")) { | ||
String s = request->getParam("inv")->value(); | ||
serial = strtoll(s.c_str(), NULL, 16); | ||
} | ||
|
||
auto inv = Hoymiles.getInverterBySerial(serial); | ||
|
||
if (inv != nullptr) { | ||
auto raw = root.createNestedArray("raw"); | ||
auto data = inv->GridProfile()->getRawData(); | ||
|
||
copyArray(&data[0], data.size(), raw); | ||
} | ||
|
||
response->setLength(); | ||
request->send(response); | ||
} |
Oops, something went wrong.