Hoymiles Lib: Remove hard coded Serial output

The serial port for output of debug information can now changed during runtime
This commit is contained in:
Thomas Basler 2022-12-19 20:52:12 +01:00
parent 3421c9a0b1
commit f689fedf4e
10 changed files with 72 additions and 51 deletions

View File

@ -35,8 +35,8 @@ void HoymilesClass::loop()
if (_radio->isIdle()) {
std::shared_ptr<InverterAbstract> iv = getInverterByPos(inverterPos);
if (iv != nullptr) {
Serial.print(F("Fetch inverter: "));
Serial.println(iv->serial(), HEX);
_messageOutput->print(F("Fetch inverter: "));
_messageOutput->println(iv->serial(), HEX);
iv->sendStatsRequest(_radio.get());
@ -48,25 +48,25 @@ void HoymilesClass::loop()
if ((iv->SystemConfigPara()->getLastLimitRequestSuccess() == CMD_NOK)
|| ((millis() - iv->SystemConfigPara()->getLastUpdateRequest() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)
&& (millis() - iv->SystemConfigPara()->getLastUpdateCommand() > HOY_SYSTEM_CONFIG_PARA_POLL_MIN_DURATION))) {
Serial.println("Request SystemConfigPara");
_messageOutput->println("Request SystemConfigPara");
iv->sendSystemConfigParaRequest(_radio.get());
}
// Set limit if required
if (iv->SystemConfigPara()->getLastLimitCommandSuccess() == CMD_NOK) {
Serial.println(F("Resend ActivePowerControl"));
_messageOutput->println(F("Resend ActivePowerControl"));
iv->resendActivePowerControlRequest(_radio.get());
}
// Set power status if required
if (iv->PowerCommand()->getLastPowerCommandSuccess() == CMD_NOK) {
Serial.println(F("Resend PowerCommand"));
_messageOutput->println(F("Resend PowerCommand"));
iv->resendPowerControlRequest(_radio.get());
}
// Fetch dev info (but first fetch stats)
if (iv->Statistics()->getLastUpdate() > 0 && (iv->DevInfo()->getLastUpdateAll() == 0 || iv->DevInfo()->getLastUpdateSimple() == 0)) {
Serial.println(F("Request device info"));
_messageOutput->println(F("Request device info"));
iv->sendDevInfoRequest(_radio.get());
}
}
@ -176,3 +176,13 @@ void HoymilesClass::setPollInterval(uint32_t interval)
{
_pollInterval = interval;
}
void HoymilesClass::setMessageOutput(Print* output)
{
_messageOutput = output;
}
Print* HoymilesClass::getMessageOutput()
{
return _messageOutput;
}

View File

@ -4,6 +4,7 @@
#include "HoymilesRadio.h"
#include "inverters/InverterAbstract.h"
#include "types.h"
#include <Print.h>
#include <SPI.h>
#include <memory>
#include <vector>
@ -16,6 +17,9 @@ public:
void init(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pinIRQ);
void loop();
void setMessageOutput(Print* output);
Print* getMessageOutput();
std::shared_ptr<InverterAbstract> addInverter(const char* name, uint64_t serial);
std::shared_ptr<InverterAbstract> getInverterByPos(uint8_t pos);
std::shared_ptr<InverterAbstract> getInverterBySerial(uint64_t serial);
@ -36,6 +40,8 @@ private:
uint32_t _pollInterval = 0;
uint32_t _lastPoll = 0;
Print* _messageOutput = &Serial;
};
extern HoymilesClass Hoymiles;

View File

@ -25,9 +25,9 @@ void HoymilesRadio::init(SPIClass* initialisedSpiBus, uint8_t pinCE, uint8_t pin
_radio->setRetries(0, 0);
_radio->maskIRQ(true, true, false); // enable only receiving interrupts
if (_radio->isChipConnected()) {
Serial.println(F("Connection successfull"));
Hoymiles.getMessageOutput()->println(F("Connection successfull"));
} else {
Serial.println(F("Connection error!!"));
Hoymiles.getMessageOutput()->println(F("Connection error!!"));
}
attachInterrupt(digitalPinToInterrupt(pinIRQ), std::bind(&HoymilesRadio::handleIntr, this), FALLING);
@ -44,7 +44,7 @@ void HoymilesRadio::loop()
}
if (_packetReceived) {
Serial.println(F("Interrupt received"));
Hoymiles.getMessageOutput()->println(F("Interrupt received"));
while (_radio->available()) {
if (!(_rxBuffer.size() > FRAGMENT_BUFFER_SIZE)) {
fragment_t f;
@ -56,7 +56,7 @@ void HoymilesRadio::loop()
_radio->read(f.fragment, f.len);
_rxBuffer.push(f);
} else {
Serial.println(F("Buffer full"));
Hoymiles.getMessageOutput()->println(F("Buffer full"));
_radio->flush_rx();
}
}
@ -76,11 +76,11 @@ void HoymilesRadio::loop()
dumpBuf(buf, f.fragment, f.len);
inv->addRxFragment(f.fragment, f.len);
} else {
Serial.println(F("Inverter Not found!"));
Hoymiles.getMessageOutput()->println(F("Inverter Not found!"));
}
} else {
Serial.println(F("Frame kaputt"));
Hoymiles.getMessageOutput()->println(F("Frame kaputt"));
}
// Remove paket from buffer even it was corrupted
@ -89,46 +89,46 @@ void HoymilesRadio::loop()
}
if (_busyFlag && _rxTimeout.occured()) {
Serial.println(F("RX Period End"));
Hoymiles.getMessageOutput()->println(F("RX Period End"));
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress());
if (nullptr != inv) {
CommandAbstract* cmd = _commandQueue.front().get();
uint8_t verifyResult = inv->verifyAllFragments(cmd);
if (verifyResult == FRAGMENT_ALL_MISSING_RESEND) {
Serial.println(F("Nothing received, resend whole request"));
Hoymiles.getMessageOutput()->println(F("Nothing received, resend whole request"));
sendLastPacketAgain();
} else if (verifyResult == FRAGMENT_ALL_MISSING_TIMEOUT) {
Serial.println(F("Nothing received, resend count exeeded"));
Hoymiles.getMessageOutput()->println(F("Nothing received, resend count exeeded"));
_commandQueue.pop();
_busyFlag = false;
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
Serial.println(F("Retransmit timeout"));
Hoymiles.getMessageOutput()->println(F("Retransmit timeout"));
_commandQueue.pop();
_busyFlag = false;
} else if (verifyResult == FRAGMENT_HANDLE_ERROR) {
Serial.println(F("Packet handling error"));
Hoymiles.getMessageOutput()->println(F("Packet handling error"));
_commandQueue.pop();
_busyFlag = false;
} else if (verifyResult > 0) {
// Perform Retransmit
Serial.print(F("Request retransmit: "));
Serial.println(verifyResult);
Hoymiles.getMessageOutput()->print(F("Request retransmit: "));
Hoymiles.getMessageOutput()->println(verifyResult);
sendRetransmitPacket(verifyResult);
} else {
// Successfull received all packages
Serial.println(F("Success"));
Hoymiles.getMessageOutput()->println(F("Success"));
_commandQueue.pop();
_busyFlag = false;
}
} else {
// If inverter was not found, assume the command is invalid
Serial.println(F("RX: Invalid inverter found"));
Hoymiles.getMessageOutput()->println(F("RX: Invalid inverter found"));
_commandQueue.pop();
_busyFlag = false;
}
@ -142,7 +142,7 @@ void HoymilesRadio::loop()
inv->clearRxFragmentBuffer();
sendEsbPacket(cmd);
} else {
Serial.println(F("TX: Invalid inverter found"));
Hoymiles.getMessageOutput()->println(F("TX: Invalid inverter found"));
_commandQueue.pop();
}
}
@ -252,12 +252,12 @@ void HoymilesRadio::sendEsbPacket(CommandAbstract* cmd)
openWritingPipe(s);
_radio->setRetries(3, 15);
Serial.print(F("TX "));
Serial.print(cmd->getCommandName());
Serial.print(F(" Channel: "));
Serial.print(_radio->getChannel());
Serial.print(F(" --> "));
cmd->dumpDataPayload(Serial);
Hoymiles.getMessageOutput()->print(F("TX "));
Hoymiles.getMessageOutput()->print(cmd->getCommandName());
Hoymiles.getMessageOutput()->print(F(" Channel: "));
Hoymiles.getMessageOutput()->print(_radio->getChannel());
Hoymiles.getMessageOutput()->print(F(" --> "));
cmd->dumpDataPayload(Hoymiles.getMessageOutput());
_radio->write(cmd->getDataPayload(), cmd->getDataSize());
_radio->setRetries(0, 0);
@ -289,10 +289,10 @@ void HoymilesRadio::dumpBuf(const char* info, uint8_t buf[], uint8_t len)
{
if (NULL != info)
Serial.print(String(info));
Hoymiles.getMessageOutput()->print(String(info));
for (uint8_t i = 0; i < len; i++) {
Serial.printf("%02X ", buf[i]);
Hoymiles.getMessageOutput()->printf("%02X ", buf[i]);
}
Serial.println(F(""));
Hoymiles.getMessageOutput()->println(F(""));
}

View File

@ -23,13 +23,13 @@ const uint8_t* CommandAbstract::getDataPayload()
return _payload;
}
void CommandAbstract::dumpDataPayload(Stream& stream)
void CommandAbstract::dumpDataPayload(Print* stream)
{
const uint8_t* payload = getDataPayload();
for (uint8_t i = 0; i < getDataSize(); i++) {
stream.printf("%02X ", payload[i]);
stream->printf("%02X ", payload[i]);
}
stream.println("");
stream->println("");
}
uint8_t CommandAbstract::getDataSize()

View File

@ -15,7 +15,7 @@ public:
virtual ~CommandAbstract() {};
const uint8_t* getDataPayload();
void dumpDataPayload(Stream& stream);
void dumpDataPayload(Print* stream);
uint8_t getDataSize();

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "InverterAbstract.h"
#include "../Hoymiles.h"
#include "crc.h"
#include <cstring>
@ -107,18 +108,18 @@ void InverterAbstract::clearRxFragmentBuffer()
void InverterAbstract::addRxFragment(uint8_t fragment[], uint8_t len)
{
if (len < 11) {
Serial.printf("FATAL: (%s, %d) fragment too short\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) fragment too short\n", __FILE__, __LINE__);
return;
}
if (len - 11 > MAX_RF_PAYLOAD_SIZE) {
Serial.printf("FATAL: (%s, %d) fragment too large\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) fragment too large\n", __FILE__, __LINE__);
return;
}
uint8_t fragmentCount = fragment[9];
if (fragmentCount == 0) {
Serial.println("ERROR: fragment number zero received and ignored");
Hoymiles.getMessageOutput()->println("ERROR: fragment number zero received and ignored");
return;
}
@ -145,7 +146,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
{
// All missing
if (_rxFragmentLastPacketId == 0) {
Serial.println(F("All missing"));
Hoymiles.getMessageOutput()->println(F("All missing"));
if (cmd->getSendCount() <= MAX_RESEND_COUNT) {
return FRAGMENT_ALL_MISSING_RESEND;
} else {
@ -156,7 +157,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
// Last fragment is missing (thte one with 0x80)
if (_rxFragmentMaxPacketId == 0) {
Serial.println(F("Last missing"));
Hoymiles.getMessageOutput()->println(F("Last missing"));
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
return _rxFragmentLastPacketId + 1;
} else {
@ -168,7 +169,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
// Middle fragment is missing
for (uint8_t i = 0; i < _rxFragmentMaxPacketId - 1; i++) {
if (!_rxFragmentBuffer[i].wasReceived) {
Serial.println(F("Middle missing"));
Hoymiles.getMessageOutput()->println(F("Middle missing"));
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
return i + 1;
} else {

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "AlarmLogParser.h"
#include "../Hoymiles.h"
#include <cstring>
void AlarmLogParser::clearBuffer()
@ -14,7 +15,7 @@ void AlarmLogParser::clearBuffer()
void AlarmLogParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > ALARM_LOG_PAYLOAD_SIZE) {
Serial.printf("FATAL: (%s, %d) stats packet too large for buffer (%d > %d)\n", __FILE__, __LINE__, offset + len, ALARM_LOG_PAYLOAD_SIZE);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) stats packet too large for buffer (%d > %d)\n", __FILE__, __LINE__, offset + len, ALARM_LOG_PAYLOAD_SIZE);
return;
}
memcpy(&_payloadAlarmLog[offset], payload, len);

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "DevInfoParser.h"
#include "../Hoymiles.h"
#include <cstring>
#define ALL 0xff
@ -36,7 +37,7 @@ void DevInfoParser::clearBufferAll()
void DevInfoParser::appendFragmentAll(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > DEV_INFO_SIZE) {
Serial.printf("FATAL: (%s, %d) dev info all packet too large for buffer\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) dev info all packet too large for buffer\n", __FILE__, __LINE__);
return;
}
memcpy(&_payloadDevInfoAll[offset], payload, len);
@ -52,7 +53,7 @@ void DevInfoParser::clearBufferSimple()
void DevInfoParser::appendFragmentSimple(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > DEV_INFO_SIZE) {
Serial.printf("FATAL: (%s, %d) dev info Simple packet too large for buffer\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) dev info Simple packet too large for buffer\n", __FILE__, __LINE__);
return;
}
memcpy(&_payloadDevInfoSimple[offset], payload, len);
@ -88,7 +89,7 @@ uint16_t DevInfoParser::getFwBuildVersion()
time_t DevInfoParser::getFwBuildDateTime()
{
struct tm timeinfo = { };
struct tm timeinfo = {};
timeinfo.tm_year = ((((uint16_t)_payloadDevInfoAll[2]) << 8) | _payloadDevInfoAll[3]) - 1900;
timeinfo.tm_mon = ((((uint16_t)_payloadDevInfoAll[4]) << 8) | _payloadDevInfoAll[5]) / 100 - 1;

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "StatisticsParser.h"
#include "../Hoymiles.h"
static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0);
static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0);
@ -42,7 +43,7 @@ void StatisticsParser::clearBuffer()
void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > STATISTIC_PACKET_SIZE) {
Serial.printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
return;
}
memcpy(&_payloadStatistic[offset], payload, len);

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "SystemConfigParaParser.h"
#include "../Hoymiles.h"
#include <cstring>
void SystemConfigParaParser::clearBuffer()
@ -14,7 +15,7 @@ void SystemConfigParaParser::clearBuffer()
void SystemConfigParaParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > (SYSTEM_CONFIG_PARA_SIZE)) {
Serial.printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
return;
}
memcpy(&_payload[offset], payload, len);