mirror of
https://github.com/tbnobody/OpenDTU.git
synced 2025-12-11 01:10:20 +01:00
Use ESP Logging Macros for hoymiles library
This commit is contained in:
@@ -17,6 +17,10 @@
|
|||||||
#include "inverters/HM_2CH.h"
|
#include "inverters/HM_2CH.h"
|
||||||
#include "inverters/HM_4CH.h"
|
#include "inverters/HM_4CH.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
HoymilesClass Hoymiles;
|
HoymilesClass Hoymiles;
|
||||||
|
|
||||||
@@ -63,7 +67,7 @@ void HoymilesClass::loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iv->getEnablePolling() || iv->getEnableCommands()) {
|
if (iv->getEnablePolling() || iv->getEnableCommands()) {
|
||||||
_messageOutput->printf("Fetch inverter: %s\n", iv->serialString().c_str());
|
ESP_LOGI(TAG, "Fetch inverter: %s", iv->serialString().c_str());
|
||||||
|
|
||||||
if (!iv->isReachable()) {
|
if (!iv->isReachable()) {
|
||||||
iv->sendChangeChannelRequest();
|
iv->sendChangeChannelRequest();
|
||||||
@@ -80,7 +84,7 @@ void HoymilesClass::loop()
|
|||||||
// Fetch limit
|
// Fetch limit
|
||||||
if (((millis() - iv->SystemConfigPara()->getLastUpdateRequest() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)
|
if (((millis() - iv->SystemConfigPara()->getLastUpdateRequest() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)
|
||||||
&& (millis() - iv->SystemConfigPara()->getLastUpdateCommand() > HOY_SYSTEM_CONFIG_PARA_POLL_MIN_DURATION))) {
|
&& (millis() - iv->SystemConfigPara()->getLastUpdateCommand() > HOY_SYSTEM_CONFIG_PARA_POLL_MIN_DURATION))) {
|
||||||
_messageOutput->printf("Request SystemConfigPara\n");
|
ESP_LOGI(TAG, "Request SystemConfigPara");
|
||||||
iv->sendSystemConfigParaRequest();
|
iv->sendSystemConfigParaRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,13 +100,13 @@ void HoymilesClass::loop()
|
|||||||
&& iv->DevInfo()->getLastUpdateSimple() > 0;
|
&& iv->DevInfo()->getLastUpdateSimple() > 0;
|
||||||
|
|
||||||
if (invalidDevInfo) {
|
if (invalidDevInfo) {
|
||||||
_messageOutput->printf("DevInfo: No Valid Data\n");
|
ESP_LOGW(TAG, "DevInfo: No Valid Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((iv->DevInfo()->getLastUpdateAll() == 0)
|
if ((iv->DevInfo()->getLastUpdateAll() == 0)
|
||||||
|| (iv->DevInfo()->getLastUpdateSimple() == 0)
|
|| (iv->DevInfo()->getLastUpdateSimple() == 0)
|
||||||
|| invalidDevInfo) {
|
|| invalidDevInfo) {
|
||||||
_messageOutput->printf("Request device info\n");
|
ESP_LOGI(TAG, "Request device info");
|
||||||
iv->sendDevInfoRequest();
|
iv->sendDevInfoRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,17 +114,17 @@ void HoymilesClass::loop()
|
|||||||
|
|
||||||
// Set limit if required
|
// Set limit if required
|
||||||
if (iv->SystemConfigPara()->getLastLimitCommandSuccess() == CMD_NOK) {
|
if (iv->SystemConfigPara()->getLastLimitCommandSuccess() == CMD_NOK) {
|
||||||
_messageOutput->printf("Resend ActivePowerControl\n");
|
ESP_LOGI(TAG, "Resend ActivePowerControl");
|
||||||
iv->resendActivePowerControlRequest();
|
iv->resendActivePowerControlRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set power status if required
|
// Set power status if required
|
||||||
if (iv->PowerCommand()->getLastPowerCommandSuccess() == CMD_NOK) {
|
if (iv->PowerCommand()->getLastPowerCommandSuccess() == CMD_NOK) {
|
||||||
_messageOutput->printf("Resend PowerCommand\n");
|
ESP_LOGI(TAG, "Resend PowerCommand");
|
||||||
iv->resendPowerControlRequest();
|
iv->resendPowerControlRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
_messageOutput->printf("Queue size - NRF: %" PRIu32 " CMT: %" PRIu32 "\n", _radioNrf->getQueueSize(), _radioCmt->getQueueSize());
|
ESP_LOGI(TAG, "Queue size - NRF: %" PRIu32 " CMT: %" PRIu32 "", _radioNrf->getQueueSize(), _radioCmt->getQueueSize());
|
||||||
_lastPoll = millis();
|
_lastPoll = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,13 +270,3 @@ void HoymilesClass::setPollInterval(const uint32_t interval)
|
|||||||
{
|
{
|
||||||
_pollInterval = interval;
|
_pollInterval = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HoymilesClass::setMessageOutput(Print* output)
|
|
||||||
{
|
|
||||||
_messageOutput = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
Print* HoymilesClass::getMessageOutput()
|
|
||||||
{
|
|
||||||
return _messageOutput;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ public:
|
|||||||
void initCMT(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int8_t pin_gpio2, const int8_t pin_gpio3);
|
void initCMT(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int8_t pin_gpio2, const int8_t pin_gpio3);
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
void setMessageOutput(Print* output);
|
|
||||||
Print* getMessageOutput();
|
|
||||||
|
|
||||||
std::shared_ptr<InverterAbstract> addInverter(const char* name, const uint64_t serial);
|
std::shared_ptr<InverterAbstract> addInverter(const char* name, const uint64_t serial);
|
||||||
std::shared_ptr<InverterAbstract> getInverterByPos(const uint8_t pos);
|
std::shared_ptr<InverterAbstract> getInverterByPos(const uint8_t pos);
|
||||||
std::shared_ptr<InverterAbstract> getInverterBySerial(const uint64_t serial);
|
std::shared_ptr<InverterAbstract> getInverterBySerial(const uint64_t serial);
|
||||||
@@ -47,8 +44,6 @@ private:
|
|||||||
|
|
||||||
uint32_t _pollInterval = 0;
|
uint32_t _pollInterval = 0;
|
||||||
uint32_t _lastPoll = 0;
|
uint32_t _lastPoll = 0;
|
||||||
|
|
||||||
Print* _messageOutput = &Serial;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HoymilesClass Hoymiles;
|
extern HoymilesClass Hoymiles;
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Thomas Basler and others
|
* Copyright (C) 2023-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "HoymilesRadio.h"
|
#include "HoymilesRadio.h"
|
||||||
#include "Hoymiles.h"
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
#include "Hoymiles.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
serial_u HoymilesRadio::DtuSerial() const
|
serial_u HoymilesRadio::DtuSerial() const
|
||||||
{
|
{
|
||||||
@@ -54,18 +58,18 @@ void HoymilesRadio::sendLastPacketAgain()
|
|||||||
void HoymilesRadio::handleReceivedPackage()
|
void HoymilesRadio::handleReceivedPackage()
|
||||||
{
|
{
|
||||||
if (_busyFlag && _rxTimeout.occured()) {
|
if (_busyFlag && _rxTimeout.occured()) {
|
||||||
Hoymiles.getMessageOutput()->printf("RX Period End\n");
|
ESP_LOGI(TAG, "RX Period End");
|
||||||
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress());
|
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress());
|
||||||
|
|
||||||
if (nullptr != inv) {
|
if (nullptr != inv) {
|
||||||
CommandAbstract* cmd = _commandQueue.front().get();
|
CommandAbstract* cmd = _commandQueue.front().get();
|
||||||
uint8_t verifyResult = inv->verifyAllFragments(*cmd);
|
uint8_t verifyResult = inv->verifyAllFragments(*cmd);
|
||||||
if (verifyResult == FRAGMENT_ALL_MISSING_RESEND) {
|
if (verifyResult == FRAGMENT_ALL_MISSING_RESEND) {
|
||||||
Hoymiles.getMessageOutput()->printf("Nothing received, resend whole request\n");
|
ESP_LOGW(TAG, "Nothing received, resend whole request");
|
||||||
sendLastPacketAgain();
|
sendLastPacketAgain();
|
||||||
|
|
||||||
} else if (verifyResult == FRAGMENT_ALL_MISSING_TIMEOUT) {
|
} else if (verifyResult == FRAGMENT_ALL_MISSING_TIMEOUT) {
|
||||||
Hoymiles.getMessageOutput()->printf("Nothing received, resend count exeeded\n");
|
ESP_LOGW(TAG, "Nothing received, resend count exeeded");
|
||||||
// Statistics: Count RX Fail No Answer
|
// Statistics: Count RX Fail No Answer
|
||||||
if (inv->RadioStats.TxRequestData > 0) {
|
if (inv->RadioStats.TxRequestData > 0) {
|
||||||
inv->RadioStats.RxFailNoAnswer++;
|
inv->RadioStats.RxFailNoAnswer++;
|
||||||
@@ -75,7 +79,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
_busyFlag = false;
|
_busyFlag = false;
|
||||||
|
|
||||||
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
|
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
|
||||||
Hoymiles.getMessageOutput()->printf("Retransmit timeout\n");
|
ESP_LOGW(TAG, "Retransmit timeout");
|
||||||
// Statistics: Count RX Fail Partial Answer
|
// Statistics: Count RX Fail Partial Answer
|
||||||
if (inv->RadioStats.TxRequestData > 0) {
|
if (inv->RadioStats.TxRequestData > 0) {
|
||||||
inv->RadioStats.RxFailPartialAnswer++;
|
inv->RadioStats.RxFailPartialAnswer++;
|
||||||
@@ -85,7 +89,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
_busyFlag = false;
|
_busyFlag = false;
|
||||||
|
|
||||||
} else if (verifyResult == FRAGMENT_HANDLE_ERROR) {
|
} else if (verifyResult == FRAGMENT_HANDLE_ERROR) {
|
||||||
Hoymiles.getMessageOutput()->printf("Packet handling error\n");
|
ESP_LOGW(TAG, "Packet handling error");
|
||||||
// Statistics: Count RX Fail Corrupt Data
|
// Statistics: Count RX Fail Corrupt Data
|
||||||
if (inv->RadioStats.TxRequestData > 0) {
|
if (inv->RadioStats.TxRequestData > 0) {
|
||||||
inv->RadioStats.RxFailCorruptData++;
|
inv->RadioStats.RxFailCorruptData++;
|
||||||
@@ -96,7 +100,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
|
|
||||||
} else if (verifyResult > 0) {
|
} else if (verifyResult > 0) {
|
||||||
// Perform Retransmit
|
// Perform Retransmit
|
||||||
Hoymiles.getMessageOutput()->printf("Request retransmit: %" PRIu8 "\n", verifyResult);
|
ESP_LOGI(TAG, "Request retransmit: %" PRIu8 "", verifyResult);
|
||||||
// Statistics: Count TX Re-Request Fragment
|
// Statistics: Count TX Re-Request Fragment
|
||||||
inv->RadioStats.TxReRequestFragment++;
|
inv->RadioStats.TxReRequestFragment++;
|
||||||
|
|
||||||
@@ -104,7 +108,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Successful received all packages
|
// Successful received all packages
|
||||||
Hoymiles.getMessageOutput()->printf("Success\n");
|
ESP_LOGI(TAG, "Success");
|
||||||
// Statistics: Count RX Success
|
// Statistics: Count RX Success
|
||||||
if (inv->RadioStats.TxRequestData > 0) {
|
if (inv->RadioStats.TxRequestData > 0) {
|
||||||
inv->RadioStats.RxSuccess++;
|
inv->RadioStats.RxSuccess++;
|
||||||
@@ -115,7 +119,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If inverter was not found, assume the command is invalid
|
// If inverter was not found, assume the command is invalid
|
||||||
Hoymiles.getMessageOutput()->printf("RX: Invalid inverter found\n");
|
ESP_LOGW(TAG, "RX: Invalid inverter found");
|
||||||
// Statistics: Count RX Fail Unknown Data
|
// Statistics: Count RX Fail Unknown Data
|
||||||
_commandQueue.pop();
|
_commandQueue.pop();
|
||||||
_busyFlag = false;
|
_busyFlag = false;
|
||||||
@@ -133,7 +137,7 @@ void HoymilesRadio::handleReceivedPackage()
|
|||||||
|
|
||||||
sendEsbPacket(*cmd);
|
sendEsbPacket(*cmd);
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("TX: Invalid inverter found\n");
|
ESP_LOGE(TAG, "TX: Invalid inverter found");
|
||||||
_commandQueue.pop();
|
_commandQueue.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,12 @@
|
|||||||
#include <TimeoutHelper.h>
|
#include <TimeoutHelper.h>
|
||||||
|
|
||||||
#ifdef HOY_DEBUG_QUEUE
|
#ifdef HOY_DEBUG_QUEUE
|
||||||
#define DEBUG_PRINT(fmt, args...) Serial.printf(fmt, ##args)
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
|
#define DEBUG_PRINT(fmt, args...) ESP_LOGD(TAG, fmt, ##args)
|
||||||
#else
|
#else
|
||||||
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
|
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
|
||||||
#endif
|
#endif
|
||||||
@@ -28,8 +33,8 @@ public:
|
|||||||
|
|
||||||
void enqueCommand(std::shared_ptr<CommandAbstract> cmd)
|
void enqueCommand(std::shared_ptr<CommandAbstract> cmd)
|
||||||
{
|
{
|
||||||
DEBUG_PRINT("Queue size before: %ld\n", _commandQueue.size());
|
DEBUG_PRINT("Queue size before: %ld", _commandQueue.size());
|
||||||
DEBUG_PRINT("Handling command %s with type %d\n", cmd.get()->getCommandName().c_str(), static_cast<uint8_t>(cmd.get()->getQueueInsertType()));
|
DEBUG_PRINT("Handling command %s with type %d", cmd.get()->getCommandName().c_str(), static_cast<uint8_t>(cmd.get()->getQueueInsertType()));
|
||||||
switch (cmd.get()->getQueueInsertType()) {
|
switch (cmd.get()->getQueueInsertType()) {
|
||||||
case QueueInsertType::RemoveOldest:
|
case QueueInsertType::RemoveOldest:
|
||||||
_commandQueue.removeDuplicatedEntries(cmd);
|
_commandQueue.removeDuplicatedEntries(cmd);
|
||||||
@@ -39,7 +44,7 @@ public:
|
|||||||
// and replaces the existing one with the new one.
|
// and replaces the existing one with the new one.
|
||||||
// (The new one will not be pushed at the end of the queue)
|
// (The new one will not be pushed at the end of the queue)
|
||||||
if (_commandQueue.countSimilarCommands(cmd) > 0) {
|
if (_commandQueue.countSimilarCommands(cmd) > 0) {
|
||||||
DEBUG_PRINT(" ... existing entry will be replaced\n");
|
DEBUG_PRINT(" ... existing entry will be replaced");
|
||||||
_commandQueue.replaceEntries(cmd);
|
_commandQueue.replaceEntries(cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -48,7 +53,7 @@ public:
|
|||||||
// Checks if the queue already contains a command like the new one
|
// Checks if the queue already contains a command like the new one
|
||||||
// and drops the new one. The new one will not be inserted.
|
// and drops the new one. The new one will not be inserted.
|
||||||
if (_commandQueue.countSimilarCommands(cmd) > 0) {
|
if (_commandQueue.countSimilarCommands(cmd) > 0) {
|
||||||
DEBUG_PRINT(" ... new entry will be dropped\n");
|
DEBUG_PRINT(" ... new entry will be dropped");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -58,10 +63,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push the command into the queue if we reach this position of the code
|
// Push the command into the queue if we reach this position of the code
|
||||||
DEBUG_PRINT(" ... new entry will be appended\n");
|
DEBUG_PRINT(" ... new entry will be appended");
|
||||||
_commandQueue.push(cmd);
|
_commandQueue.push(cmd);
|
||||||
|
|
||||||
DEBUG_PRINT("Queue size after: %ld\n", _commandQueue.size());
|
DEBUG_PRINT("Queue size after: %ld", _commandQueue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023-2024 Thomas Basler and others
|
* Copyright (C) 2023-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "HoymilesRadio_CMT.h"
|
#include "HoymilesRadio_CMT.h"
|
||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include <FunctionalInterrupt.h>
|
#include <FunctionalInterrupt.h>
|
||||||
#include <frozen/map.h>
|
#include <frozen/map.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
constexpr CountryFrequencyDefinition_t make_value(FrequencyBand_t Band, uint32_t Freq_Legal_Min, uint32_t Freq_Legal_Max, uint32_t Freq_Default, uint32_t Freq_StartUp)
|
constexpr CountryFrequencyDefinition_t make_value(FrequencyBand_t Band, uint32_t Freq_Legal_Min, uint32_t Freq_Legal_Max, uint32_t Freq_Default, uint32_t Freq_StartUp)
|
||||||
{
|
{
|
||||||
@@ -35,16 +39,16 @@ uint32_t HoymilesRadio_CMT::getFrequencyFromChannel(const uint8_t channel) const
|
|||||||
uint8_t HoymilesRadio_CMT::getChannelFromFrequency(const uint32_t frequency) const
|
uint8_t HoymilesRadio_CMT::getChannelFromFrequency(const uint32_t frequency) const
|
||||||
{
|
{
|
||||||
if ((frequency % getChannelWidth()) != 0) {
|
if ((frequency % getChannelWidth()) != 0) {
|
||||||
Hoymiles.getMessageOutput()->printf("%.3f MHz is not divisible by %" PRIu32 " kHz!\n", frequency / 1000000.0, getChannelWidth());
|
ESP_LOGE(TAG, "%.3f MHz is not divisible by %" PRIu32 " kHz!", frequency / 1000000.0, getChannelWidth());
|
||||||
return 0xFF; // ERROR
|
return 0xFF; // ERROR
|
||||||
}
|
}
|
||||||
if (frequency < getMinFrequency() || frequency > getMaxFrequency()) {
|
if (frequency < getMinFrequency() || frequency > getMaxFrequency()) {
|
||||||
Hoymiles.getMessageOutput()->printf("%.2f MHz is out of Hoymiles/CMT range! (%.2f MHz - %.2f MHz)\n",
|
ESP_LOGE(TAG, "%.2f MHz is out of Hoymiles/CMT range! (%.2f MHz - %.2f MHz)",
|
||||||
frequency / 1000000.0, getMinFrequency() / 1000000.0, getMaxFrequency() / 1000000.0);
|
frequency / 1000000.0, getMinFrequency() / 1000000.0, getMaxFrequency() / 1000000.0);
|
||||||
return 0xFF; // ERROR
|
return 0xFF; // ERROR
|
||||||
}
|
}
|
||||||
if (frequency < countryDefinition.at(_countryMode).Freq_Legal_Min || frequency > countryDefinition.at(_countryMode).Freq_Legal_Max) {
|
if (frequency < countryDefinition.at(_countryMode).Freq_Legal_Min || frequency > countryDefinition.at(_countryMode).Freq_Legal_Max) {
|
||||||
Hoymiles.getMessageOutput()->printf("!!! caution: %.2f MHz is out of region legal range! (%" PRIu32 " - %" PRIu32 " MHz)\n",
|
ESP_LOGE(TAG, "!!! caution: %.2f MHz is out of region legal range! (%" PRIu32 " - %" PRIu32 " MHz)",
|
||||||
frequency / 1000000.0,
|
frequency / 1000000.0,
|
||||||
static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Min / 1e6),
|
static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Min / 1e6),
|
||||||
static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Max / 1e6));
|
static_cast<uint32_t>(countryDefinition.at(_countryMode).Freq_Legal_Max / 1e6));
|
||||||
@@ -96,10 +100,10 @@ void HoymilesRadio_CMT::init(const int8_t pin_sdio, const int8_t pin_clk, const
|
|||||||
cmtSwitchDtuFreq(_inverterTargetFrequency); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched
|
cmtSwitchDtuFreq(_inverterTargetFrequency); // start dtu at work freqency, for fast Rx if inverter is already on and frequency switched
|
||||||
|
|
||||||
if (!_radio->isChipConnected()) {
|
if (!_radio->isChipConnected()) {
|
||||||
Hoymiles.getMessageOutput()->printf("CMT2300A: Connection error!!\n");
|
ESP_LOGE(TAG, "CMT2300A: Connection error!!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Hoymiles.getMessageOutput()->printf("CMT2300A: Connection successful\n");
|
ESP_LOGI(TAG, "CMT2300A: Connection successful");
|
||||||
|
|
||||||
if (pin_gpio2 >= 0) {
|
if (pin_gpio2 >= 0) {
|
||||||
attachInterrupt(digitalPinToInterrupt(pin_gpio2), std::bind(&HoymilesRadio_CMT::handleInt1, this), RISING);
|
attachInterrupt(digitalPinToInterrupt(pin_gpio2), std::bind(&HoymilesRadio_CMT::handleInt1, this), RISING);
|
||||||
@@ -127,10 +131,10 @@ void HoymilesRadio_CMT::loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_packetReceived) {
|
if (_packetReceived) {
|
||||||
Hoymiles.getMessageOutput()->printf("Interrupt received\n");
|
ESP_LOGV(TAG, "Interrupt received");
|
||||||
while (_radio->available()) {
|
while (_radio->available()) {
|
||||||
if (_rxBuffer.size() > FRAGMENT_BUFFER_SIZE) {
|
if (_rxBuffer.size() > FRAGMENT_BUFFER_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("CMT2300A: Buffer full\n");
|
ESP_LOGE(TAG, "CMT2300A: Buffer full");
|
||||||
_radio->flush_rx();
|
_radio->flush_rx();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -164,17 +168,17 @@ void HoymilesRadio_CMT::loop()
|
|||||||
|
|
||||||
if (nullptr != inv) {
|
if (nullptr != inv) {
|
||||||
// Save packet in inverter rx buffer
|
// Save packet in inverter rx buffer
|
||||||
Hoymiles.getMessageOutput()->printf("RX %.2f MHz --> %s | %" PRId8 " dBm\n",
|
ESP_LOGD(TAG, "RX %.2f MHz --> %s | %" PRId8 " dBm",
|
||||||
getFrequencyFromChannel(f.channel) / 1000000.0, Utils::dumpArray(f.fragment, f.len).c_str(), f.rssi);
|
getFrequencyFromChannel(f.channel) / 1000000.0, Utils::dumpArray(f.fragment, f.len).c_str(), f.rssi);
|
||||||
|
|
||||||
inv->addRxFragment(f.fragment, f.len, f.rssi);
|
inv->addRxFragment(f.fragment, f.len, f.rssi);
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("Inverter Not found!\n");
|
ESP_LOGE(TAG, "Inverter Not found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("Frame kaputt\n"); // ;-)
|
ESP_LOGW(TAG, "Frame kaputt"); // ;-)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove paket from buffer even it was corrupted
|
// Remove paket from buffer even it was corrupted
|
||||||
@@ -192,9 +196,9 @@ void HoymilesRadio_CMT::setPALevel(const int8_t paLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_radio->setPALevel(paLevel)) {
|
if (_radio->setPALevel(paLevel)) {
|
||||||
Hoymiles.getMessageOutput()->printf("CMT TX power set to %" PRId8 " dBm\n", paLevel);
|
ESP_LOGI(TAG, "CMT TX power set to %" PRId8 " dBm", paLevel);
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("CMT TX power %" PRId8 " dBm is not defined! (min: -10 dBm, max: 20 dBm)\n", paLevel);
|
ESP_LOGE(TAG, "CMT TX power %" PRId8 " dBm is not defined! (min: -10 dBm, max: 20 dBm)", paLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,11 +276,11 @@ void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract& cmd)
|
|||||||
cmtSwitchDtuFreq(getInvBootFrequency());
|
cmtSwitchDtuFreq(getInvBootFrequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
Hoymiles.getMessageOutput()->printf("TX %s %.2f MHz --> %s\n",
|
ESP_LOGD(TAG, "TX %s %.2f MHz --> %s",
|
||||||
cmd.getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()) / 1000000.0, cmd.dumpDataPayload().c_str());
|
cmd.getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()) / 1000000.0, cmd.dumpDataPayload().c_str());
|
||||||
|
|
||||||
if (!_radio->write(cmd.getDataPayload(), cmd.getDataSize())) {
|
if (!_radio->write(cmd.getDataPayload(), cmd.getDataSize())) {
|
||||||
Hoymiles.getMessageOutput()->printf("TX SPI Timeout\n");
|
ESP_LOGE(TAG, "TX SPI Timeout");
|
||||||
}
|
}
|
||||||
cmtSwitchDtuFreq(_inverterTargetFrequency);
|
cmtSwitchDtuFreq(_inverterTargetFrequency);
|
||||||
_radio->startListening();
|
_radio->startListening();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Thomas Basler and others
|
* Copyright (C) 2022-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "HoymilesRadio_NRF.h"
|
#include "HoymilesRadio_NRF.h"
|
||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "commands/RequestFrameCommand.h"
|
#include "commands/RequestFrameCommand.h"
|
||||||
#include <Every.h>
|
#include <Every.h>
|
||||||
#include <FunctionalInterrupt.h>
|
#include <FunctionalInterrupt.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
void HoymilesRadio_NRF::init(SPIClass* initialisedSpiBus, const uint8_t pinCE, const uint8_t pinIRQ)
|
void HoymilesRadio_NRF::init(SPIClass* initialisedSpiBus, const uint8_t pinCE, const uint8_t pinIRQ)
|
||||||
{
|
{
|
||||||
@@ -25,10 +29,10 @@ void HoymilesRadio_NRF::init(SPIClass* initialisedSpiBus, const uint8_t pinCE, c
|
|||||||
_radio->setRetries(0, 0);
|
_radio->setRetries(0, 0);
|
||||||
_radio->maskIRQ(true, true, false); // enable only receiving interrupts
|
_radio->maskIRQ(true, true, false); // enable only receiving interrupts
|
||||||
if (!_radio->isChipConnected()) {
|
if (!_radio->isChipConnected()) {
|
||||||
Hoymiles.getMessageOutput()->printf("NRF: Connection error!!\n");
|
ESP_LOGE(TAG, "NRF: Connection error!!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Hoymiles.getMessageOutput()->printf("NRF: Connection successful\n");
|
ESP_LOGI(TAG, "NRF: Connection successful");
|
||||||
|
|
||||||
attachInterrupt(digitalPinToInterrupt(pinIRQ), std::bind(&HoymilesRadio_NRF::handleIntr, this), FALLING);
|
attachInterrupt(digitalPinToInterrupt(pinIRQ), std::bind(&HoymilesRadio_NRF::handleIntr, this), FALLING);
|
||||||
|
|
||||||
@@ -49,10 +53,10 @@ void HoymilesRadio_NRF::loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_packetReceived) {
|
if (_packetReceived) {
|
||||||
Hoymiles.getMessageOutput()->printf("Interrupt received\n");
|
ESP_LOGV(TAG, "Interrupt received");
|
||||||
while (_radio->available()) {
|
while (_radio->available()) {
|
||||||
if (_rxBuffer.size() > FRAGMENT_BUFFER_SIZE) {
|
if (_rxBuffer.size() > FRAGMENT_BUFFER_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("NRF: Buffer full\n");
|
ESP_LOGE(TAG, "NRF: Buffer full");
|
||||||
_radio->flush_rx();
|
_radio->flush_rx();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -76,16 +80,16 @@ void HoymilesRadio_NRF::loop()
|
|||||||
|
|
||||||
if (nullptr != inv) {
|
if (nullptr != inv) {
|
||||||
// Save packet in inverter rx buffer
|
// Save packet in inverter rx buffer
|
||||||
Hoymiles.getMessageOutput()->printf("RX Channel: %" PRIu8 " --> %s | %" PRId8 " dBm\n",
|
ESP_LOGD(TAG, "RX Channel: %" PRIu8 " --> %s | %" PRId8 " dBm",
|
||||||
f.channel, Utils::dumpArray(f.fragment, f.len).c_str(), f.rssi);
|
f.channel, Utils::dumpArray(f.fragment, f.len).c_str(), f.rssi);
|
||||||
|
|
||||||
inv->addRxFragment(f.fragment, f.len, f.rssi);
|
inv->addRxFragment(f.fragment, f.len, f.rssi);
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("Inverter Not found!\n");
|
ESP_LOGE(TAG, "Inverter Not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Hoymiles.getMessageOutput()->printf("Frame kaputt\n");
|
ESP_LOGW(TAG, "Frame kaputt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove paket from buffer even it was corrupted
|
// Remove paket from buffer even it was corrupted
|
||||||
@@ -182,7 +186,7 @@ void HoymilesRadio_NRF::sendEsbPacket(CommandAbstract& cmd)
|
|||||||
openWritingPipe(s);
|
openWritingPipe(s);
|
||||||
_radio->setRetries(3, 15);
|
_radio->setRetries(3, 15);
|
||||||
|
|
||||||
Hoymiles.getMessageOutput()->printf("TX %s Channel: %" PRIu8 " --> %s\n",
|
ESP_LOGD(TAG, "TX %s Channel: %" PRIu8 " --> %s",
|
||||||
cmd.getCommandName().c_str(), _radio->getChannel(), cmd.dumpDataPayload().c_str());
|
cmd.getCommandName().c_str(), _radio->getChannel(), cmd.dumpDataPayload().c_str());
|
||||||
_radio->write(cmd.getDataPayload(), cmd.getDataSize());
|
_radio->write(cmd.getDataPayload(), cmd.getDataSize());
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
* Copyright (C) 2022-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -19,8 +19,11 @@ Command structure:
|
|||||||
ID Target Addr Source Addr Idx DT ? Time Gap Password CRC16 CRC8
|
ID Target Addr Source Addr Idx DT ? Time Gap Password CRC16 CRC8
|
||||||
*/
|
*/
|
||||||
#include "RealTimeRunDataCommand.h"
|
#include "RealTimeRunDataCommand.h"
|
||||||
#include "Hoymiles.h"
|
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
RealTimeRunDataCommand::RealTimeRunDataCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
RealTimeRunDataCommand::RealTimeRunDataCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(inv, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
@@ -48,7 +51,7 @@ bool RealTimeRunDataCommand::handleResponse(const fragment_t fragment[], const u
|
|||||||
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
||||||
const uint8_t expectedSize = _inv->Statistics()->getExpectedByteCount();
|
const uint8_t expectedSize = _inv->Statistics()->getExpectedByteCount();
|
||||||
if (fragmentsSize < expectedSize) {
|
if (fragmentsSize < expectedSize) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %" PRIu8 ", min expected size: %" PRIu8 "\n",
|
ESP_LOGE(TAG, "ERROR in %s: Received fragment size: %" PRIu8 ", min expected size: %" PRIu8 "",
|
||||||
getCommandName().c_str(), fragmentsSize, expectedSize);
|
getCommandName().c_str(), fragmentsSize, expectedSize);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
* Copyright (C) 2022-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -19,8 +19,11 @@ Command structure:
|
|||||||
ID Target Addr Source Addr Idx DT ? Time Gap Password CRC16 CRC8
|
ID Target Addr Source Addr Idx DT ? Time Gap Password CRC16 CRC8
|
||||||
*/
|
*/
|
||||||
#include "SystemConfigParaCommand.h"
|
#include "SystemConfigParaCommand.h"
|
||||||
#include "Hoymiles.h"
|
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
SystemConfigParaCommand::SystemConfigParaCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
SystemConfigParaCommand::SystemConfigParaCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(inv, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
@@ -48,7 +51,7 @@ bool SystemConfigParaCommand::handleResponse(const fragment_t fragment[], const
|
|||||||
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
||||||
const uint8_t expectedSize = _inv->SystemConfigPara()->getExpectedByteCount();
|
const uint8_t expectedSize = _inv->SystemConfigPara()->getExpectedByteCount();
|
||||||
if (fragmentsSize < expectedSize) {
|
if (fragmentsSize < expectedSize) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %" PRIu8 ", min expected size: %" PRIu8 "\n",
|
ESP_LOGE(TAG, "ERROR in %s: Received fragment size: %" PRIu8 ", min expected size: %" PRIu8 "",
|
||||||
getCommandName().c_str(), fragmentsSize, expectedSize);
|
getCommandName().c_str(), fragmentsSize, expectedSize);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Thomas Basler and others
|
* Copyright (C) 2022-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "InverterAbstract.h"
|
#include "InverterAbstract.h"
|
||||||
#include "../Hoymiles.h"
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
InverterAbstract::InverterAbstract(HoymilesRadio* radio, const uint64_t serial)
|
InverterAbstract::InverterAbstract(HoymilesRadio* radio, const uint64_t serial)
|
||||||
{
|
{
|
||||||
@@ -195,12 +198,12 @@ void InverterAbstract::addRxFragment(const uint8_t fragment[], const uint8_t len
|
|||||||
_lastRssi = rssi;
|
_lastRssi = rssi;
|
||||||
|
|
||||||
if (len < 11) {
|
if (len < 11) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) fragment too short\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) fragment too short", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len - 11 > MAX_RF_PAYLOAD_SIZE) {
|
if (len - 11 > MAX_RF_PAYLOAD_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) fragment too large\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "FATAL: (%s, %d) fragment too large", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,12 +213,12 @@ void InverterAbstract::addRxFragment(const uint8_t fragment[], const uint8_t len
|
|||||||
const uint8_t fragmentId = fragmentCount & 0b01111111; // fragmentId is 1 based
|
const uint8_t fragmentId = fragmentCount & 0b01111111; // fragmentId is 1 based
|
||||||
|
|
||||||
if (fragmentId == 0) {
|
if (fragmentId == 0) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR: fragment id zero received and ignored\n");
|
ESP_LOGE(TAG, "Fragment id zero received and ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragmentId >= MAX_RF_FRAGMENT_COUNT) {
|
if (fragmentId >= MAX_RF_FRAGMENT_COUNT) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR: fragment id %" PRIu8 " is too large for buffer and ignored\n", fragmentId);
|
ESP_LOGE(TAG, "Fragment id %" PRIu8 " is too large for buffer and ignored", fragmentId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +242,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
{
|
{
|
||||||
// All missing
|
// All missing
|
||||||
if (_rxFragmentLastPacketId == 0) {
|
if (_rxFragmentLastPacketId == 0) {
|
||||||
Hoymiles.getMessageOutput()->printf("All missing\n");
|
ESP_LOGW(TAG, "All missing");
|
||||||
if (cmd.getSendCount() <= cmd.getMaxResendCount()) {
|
if (cmd.getSendCount() <= cmd.getMaxResendCount()) {
|
||||||
return FRAGMENT_ALL_MISSING_RESEND;
|
return FRAGMENT_ALL_MISSING_RESEND;
|
||||||
} else {
|
} else {
|
||||||
@@ -250,7 +253,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
|
|
||||||
// Last fragment is missing (the one with 0x80)
|
// Last fragment is missing (the one with 0x80)
|
||||||
if (_rxFragmentMaxPacketId == 0) {
|
if (_rxFragmentMaxPacketId == 0) {
|
||||||
Hoymiles.getMessageOutput()->printf("Last missing\n");
|
ESP_LOGW(TAG, "Last missing");
|
||||||
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
||||||
return _rxFragmentLastPacketId + 1;
|
return _rxFragmentLastPacketId + 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -262,7 +265,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
// Middle fragment is missing
|
// Middle fragment is missing
|
||||||
for (uint8_t i = 0; i < _rxFragmentMaxPacketId - 1; i++) {
|
for (uint8_t i = 0; i < _rxFragmentMaxPacketId - 1; i++) {
|
||||||
if (!_rxFragmentBuffer[i].wasReceived) {
|
if (!_rxFragmentBuffer[i].wasReceived) {
|
||||||
Hoymiles.getMessageOutput()->printf("Middle missing\n");
|
ESP_LOGW(TAG, "Middle missing");
|
||||||
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
||||||
return i + 1;
|
return i + 1;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
* Copyright (C) 2022-2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -23,8 +23,11 @@ Data structure:
|
|||||||
ID Source Addr Target Addr Idx ? wcode ? Start End ? ? ? ? wcode CRC8
|
ID Source Addr Target Addr Idx ? wcode ? Start End ? ? ? ? wcode CRC8
|
||||||
*/
|
*/
|
||||||
#include "AlarmLogParser.h"
|
#include "AlarmLogParser.h"
|
||||||
#include "../Hoymiles.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
const std::array<const AlarmMessage_t, ALARM_MSG_COUNT> AlarmLogParser::_alarmMessages = { {
|
const std::array<const AlarmMessage_t, ALARM_MSG_COUNT> AlarmLogParser::_alarmMessages = { {
|
||||||
{ AlarmMessageType_t::ALL, 1, "Inverter start", "Wechselrichter gestartet", "L'onduleur a démarré" },
|
{ AlarmMessageType_t::ALL, 1, "Inverter start", "Wechselrichter gestartet", "L'onduleur a démarré" },
|
||||||
@@ -205,7 +208,7 @@ void AlarmLogParser::clearBuffer()
|
|||||||
void AlarmLogParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void AlarmLogParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > ALARM_LOG_PAYLOAD_SIZE) {
|
if (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);
|
ESP_LOGE(TAG, "(%s, %d) stats packet too large for buffer (%d > %d)", __FILE__, __LINE__, offset + len, ALARM_LOG_PAYLOAD_SIZE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payloadAlarmLog[offset], payload, len);
|
memcpy(&_payloadAlarmLog[offset], payload, len);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 - 2024 Thomas Basler and others
|
* Copyright (C) 2022 - 2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -28,8 +28,12 @@ Data structure (DevInfoSimpleCommand):
|
|||||||
ID Source Addr Target Addr Idx FW Version HW Part No. HW Version ? ? ? CRC16 CRC8
|
ID Source Addr Target Addr Idx FW Version HW Part No. HW Version ? ? ? CRC16 CRC8
|
||||||
*/
|
*/
|
||||||
#include "DevInfoParser.h"
|
#include "DevInfoParser.h"
|
||||||
#include "../Hoymiles.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
#define ALL 0xff
|
#define ALL 0xff
|
||||||
|
|
||||||
@@ -103,7 +107,7 @@ void DevInfoParser::clearBufferAll()
|
|||||||
void DevInfoParser::appendFragmentAll(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void DevInfoParser::appendFragmentAll(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > DEV_INFO_SIZE) {
|
if (offset + len > DEV_INFO_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) dev info all packet too large for buffer\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) dev info all packet too large for buffer", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payloadDevInfoAll[offset], payload, len);
|
memcpy(&_payloadDevInfoAll[offset], payload, len);
|
||||||
@@ -119,7 +123,7 @@ void DevInfoParser::clearBufferSimple()
|
|||||||
void DevInfoParser::appendFragmentSimple(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void DevInfoParser::appendFragmentSimple(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > DEV_INFO_SIZE) {
|
if (offset + len > DEV_INFO_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) dev info Simple packet too large for buffer\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) dev info Simple packet too large for buffer", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payloadDevInfoSimple[offset], payload, len);
|
memcpy(&_payloadDevInfoSimple[offset], payload, len);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 - 2024 Thomas Basler and others
|
* Copyright (C) 2023 - 2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -20,11 +20,14 @@ ID Source Addr Target Addr Idx Profile ID Profile Version Section ID
|
|||||||
The number of values depends on the respective section and its version. After the last value of a section follows the next section id.
|
The number of values depends on the respective section and its version. After the last value of a section follows the next section id.
|
||||||
*/
|
*/
|
||||||
#include "GridProfileParser.h"
|
#include "GridProfileParser.h"
|
||||||
#include "../Hoymiles.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <esp_log.h>
|
||||||
#include <frozen/map.h>
|
#include <frozen/map.h>
|
||||||
#include <frozen/string.h>
|
#include <frozen/string.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
const std::array<const ProfileType_t, PROFILE_TYPE_COUNT> GridProfileParser::_profileTypes = { {
|
const std::array<const ProfileType_t, PROFILE_TYPE_COUNT> GridProfileParser::_profileTypes = { {
|
||||||
{ 0x02, 0x00, "US - NA_IEEE1547_240V" },
|
{ 0x02, 0x00, "US - NA_IEEE1547_240V" },
|
||||||
{ 0x03, 0x00, "DE - DE_VDE4105_2018" },
|
{ 0x03, 0x00, "DE - DE_VDE4105_2018" },
|
||||||
@@ -377,7 +380,7 @@ void GridProfileParser::clearBuffer()
|
|||||||
void GridProfileParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void GridProfileParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > GRID_PROFILE_SIZE) {
|
if (offset + len > GRID_PROFILE_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) grid profile packet too large for buffer\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) grid profile packet too large for buffer", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payloadGridProfile[offset], payload, len);
|
memcpy(&_payloadGridProfile[offset], payload, len);
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 - 2023 Thomas Basler and others
|
* Copyright (C) 2022 - 2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "StatisticsParser.h"
|
#include "StatisticsParser.h"
|
||||||
#include "../Hoymiles.h"
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
static float calcTotalYieldTotal(StatisticsParser* iv, uint8_t arg0);
|
static float calcTotalYieldTotal(StatisticsParser* iv, uint8_t arg0);
|
||||||
static float calcTotalYieldDay(StatisticsParser* iv, uint8_t arg0);
|
static float calcTotalYieldDay(StatisticsParser* iv, uint8_t arg0);
|
||||||
@@ -89,7 +92,7 @@ void StatisticsParser::clearBuffer()
|
|||||||
void StatisticsParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void StatisticsParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > STATISTIC_PACKET_SIZE) {
|
if (offset + len > STATISTIC_PACKET_SIZE) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) stats packet too large for buffer", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payloadStatistic[offset], payload, len);
|
memcpy(&_payloadStatistic[offset], payload, len);
|
||||||
@@ -109,7 +112,7 @@ void StatisticsParser::endAppendFragment()
|
|||||||
// check if current yield day is smaller then last cached yield day
|
// check if current yield day is smaller then last cached yield day
|
||||||
if (getChannelFieldValue(TYPE_DC, c, FLD_YD) < _lastYieldDay[static_cast<uint8_t>(c)]) {
|
if (getChannelFieldValue(TYPE_DC, c, FLD_YD) < _lastYieldDay[static_cast<uint8_t>(c)]) {
|
||||||
// currently all values are zero --> Add last known values to offset
|
// currently all values are zero --> Add last known values to offset
|
||||||
Hoymiles.getMessageOutput()->printf("Yield Day reset detected!\n");
|
ESP_LOGI(TAG, "Yield Day reset detected!");
|
||||||
|
|
||||||
setChannelFieldOffset(TYPE_DC, c, FLD_YD, _lastYieldDay[static_cast<uint8_t>(c)]);
|
setChannelFieldOffset(TYPE_DC, c, FLD_YD, _lastYieldDay[static_cast<uint8_t>(c)]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 - 2024 Thomas Basler and others
|
* Copyright (C) 2022 - 2025 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -17,8 +17,11 @@ Data structure:
|
|||||||
ID Source Addr Target Addr Idx ? Limit percent ? ? ? ? ? CRC16 CRC8
|
ID Source Addr Target Addr Idx ? Limit percent ? ? ? ? ? CRC16 CRC8
|
||||||
*/
|
*/
|
||||||
#include "SystemConfigParaParser.h"
|
#include "SystemConfigParaParser.h"
|
||||||
#include "../Hoymiles.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
#undef TAG
|
||||||
|
static const char* TAG = "hoymiles";
|
||||||
|
|
||||||
SystemConfigParaParser::SystemConfigParaParser()
|
SystemConfigParaParser::SystemConfigParaParser()
|
||||||
: Parser()
|
: Parser()
|
||||||
@@ -35,7 +38,7 @@ void SystemConfigParaParser::clearBuffer()
|
|||||||
void SystemConfigParaParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
void SystemConfigParaParser::appendFragment(const uint8_t offset, const uint8_t* payload, const uint8_t len)
|
||||||
{
|
{
|
||||||
if (offset + len > (SYSTEM_CONFIG_PARA_SIZE)) {
|
if (offset + len > (SYSTEM_CONFIG_PARA_SIZE)) {
|
||||||
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
|
ESP_LOGE(TAG, "(%s, %d) stats packet too large for buffer", __FILE__, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&_payload[offset], payload, len);
|
memcpy(&_payload[offset], payload, len);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "InverterSettings.h"
|
#include "InverterSettings.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MessageOutput.h"
|
|
||||||
#include "PinMapping.h"
|
#include "PinMapping.h"
|
||||||
#include "SunPosition.h"
|
#include "SunPosition.h"
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
@@ -28,7 +27,6 @@ void InverterSettingsClass::init(Scheduler& scheduler)
|
|||||||
|
|
||||||
// Initialize inverter communication
|
// Initialize inverter communication
|
||||||
ESP_LOGI(TAG, "Initialize Hoymiles interface...");
|
ESP_LOGI(TAG, "Initialize Hoymiles interface...");
|
||||||
Hoymiles.setMessageOutput(&MessageOutput);
|
|
||||||
Hoymiles.init();
|
Hoymiles.init();
|
||||||
|
|
||||||
if (!PinMapping.isValidNrf24Config() && !PinMapping.isValidCmt2300Config()) {
|
if (!PinMapping.isValidNrf24Config() && !PinMapping.isValidCmt2300Config()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user