Skip to content

Commit

Permalink
Merge branch 'hoylabs:development' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
Snoopy-HSS authored Jan 14, 2025
2 parents faff95c + 13904a4 commit 3fc91ee
Show file tree
Hide file tree
Showing 54 changed files with 1,244 additions and 1,009 deletions.
2 changes: 1 addition & 1 deletion include/MqttSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MqttSettingsClass {
void unsubscribe(const String& topic);

String getPrefix() const;
String getClientId();
String getClientId() const;

private:
void NetworkEvent(network_event event);
Expand Down
12 changes: 9 additions & 3 deletions lang/es.lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"Refreshing": "Refrescando",
"Pull": "Tira hacia abajo para refrescar",
"Release": "Soltar para refrescar",
"Close": "Cerrar"
"Close": "Cerrar",
"Yes": "Yes",
"No": "No"
},
"wait": {
"NotReady": "OpenDTU is not yet ready",
Expand Down Expand Up @@ -193,7 +195,10 @@
"FirmwareVersion": "Versión del firmware",
"FirmwareBuildDate": "Fecha de construcción del firmware",
"HardwarePartNumber": "Número de parte de hardware",
"HardwareVersion": "Versión de hardware"
"HardwareVersion": "Versión de hardware",
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
"Yes": "@:base.Yes",
"No": "@:base.No"
},
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
Expand Down Expand Up @@ -637,7 +642,8 @@
"TimeSync": "El reloj aún no ha sido sincronizado. Sin un reloj correctamente ajustado, no se realizan solicitudes al inversor. Esto es normal poco después del inicio. Sin embargo, después de un tiempo de ejecución más largo (>1 minuto), indica que el servidor NTP no es accesible.",
"TimeSyncLink": "Por favor, verifica la configuración de tu hora.",
"DefaultPassword": "Estás utilizando la contraseña predeterminada para la interfaz web y el punto de acceso de emergencia. Esto potencialmente es inseguro.",
"DefaultPasswordLink": "Por favor, cambia la contraseña."
"DefaultPasswordLink": "Por favor, cambia la contraseña.",
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu-onbattery.net/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
},
"deviceadmin": {
"DeviceManager": "Administrador de Dispositivos",
Expand Down
12 changes: 9 additions & 3 deletions lang/it.lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"Refreshing": "Aggiorna",
"Pull": "Trascina in basso per aggiornare",
"Release": "Rilascia per aggiornare",
"Close": "Chiudi"
"Close": "Chiudi",
"Yes": "Yes",
"No": "No"
},
"wait": {
"NotReady": "OpenDTU is not yet ready",
Expand Down Expand Up @@ -193,7 +195,10 @@
"FirmwareVersion": "Versione Firmware",
"FirmwareBuildDate": "Data Firmware",
"HardwarePartNumber": "Hardware Part Number",
"HardwareVersion": "Hardware Version"
"HardwareVersion": "Hardware Version",
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
"Yes": "@:base.Yes",
"No": "@:base.No"
},
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
Expand Down Expand Up @@ -637,7 +642,8 @@
"TimeSync": "La Data/Ora non sono state sincronizzate, ed in tal caso non è possibile eseguire richieste all'inverter. Questa condizione è normale appena avviato, tuttavia dopo un po' (>1 minuto), questa situazione potrebbe indicare un problema di accesso al server NTP.",
"TimeSyncLink": "Controlla le impostazioni Data/Ora.",
"DefaultPassword": "Stai usando la password di default per accedere all'interfaccia web e per la modalità Access Point di emergenza. Questo può portare ad un rischio di sicurezza.",
"DefaultPasswordLink": "Per favore cambia la password."
"DefaultPasswordLink": "Per favore cambia la password.",
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu-onbattery.net/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
},
"deviceadmin": {
"DeviceManager": "Device-Manager",
Expand Down
6 changes: 6 additions & 0 deletions lib/CpuTemperature/src/CpuTemperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ CpuTemperatureClass CpuTemperature;

float CpuTemperatureClass::read()
{
#ifdef CONFIG_IDF_TARGET_ESP32S2
// Disabling temperature reading for ESP32-S2 models as it might lead to WDT resets.
// See: https://github.com/espressif/esp-idf/issues/8088
return NAN;
#endif

std::lock_guard<std::mutex> lock(_mutex);

float temperature = NAN;
Expand Down
4 changes: 3 additions & 1 deletion lib/Hoymiles/src/Hoymiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void HoymilesClass::loop()
}
}

if (iv != nullptr && iv->getRadio()->isInitialized() && iv->getRadio()->isQueueEmpty()) {
if (iv != nullptr && iv->getRadio()->isInitialized()) {

if (iv->getZeroValuesIfUnreachable() && !iv->isReachable()) {
iv->Statistics()->zeroRuntimeData();
Expand Down Expand Up @@ -119,6 +119,7 @@ void HoymilesClass::loop()
iv->sendGridOnProFileParaRequest();
}

_messageOutput->printf("Queue size - NRF: %" PRId32 " CMT: %" PRId32 "\r\n", _radioNrf->getQueueSize(), _radioCmt->getQueueSize());
_lastPoll = millis();
}

Expand Down Expand Up @@ -229,6 +230,7 @@ void HoymilesClass::removeInverterBySerial(const uint64_t serial)
for (uint8_t i = 0; i < _inverters.size(); i++) {
if (_inverters[i]->serial() == serial) {
std::lock_guard<std::mutex> lock(_mutex);
_inverters[i]->getRadio()->removeCommands(_inverters[i].get());
_inverters.erase(_inverters.begin() + i);
return;
}
Expand Down
15 changes: 15 additions & 0 deletions lib/Hoymiles/src/HoymilesRadio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ bool HoymilesRadio::isInitialized() const
return _isInitialized;
}

void HoymilesRadio::removeCommands(InverterAbstract* inv)
{
_commandQueue.removeAllEntriesForInverter(inv);
}

uint8_t HoymilesRadio::countSimilarCommands(std::shared_ptr<CommandAbstract> cmd)
{
return _commandQueue.countSimilarCommands(cmd);
}

bool HoymilesRadio::isIdle() const
{
return !_busyFlag;
Expand All @@ -165,3 +175,8 @@ bool HoymilesRadio::isQueueEmpty() const
{
return _commandQueue.size() == 0;
}

uint32_t HoymilesRadio::getQueueSize() const
{
return _commandQueue.size();
}
49 changes: 46 additions & 3 deletions lib/Hoymiles/src/HoymilesRadio.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include "Arduino.h"
#include "commands/CommandAbstract.h"
#include "queue/CommandQueue.h"
#include "types.h"
#include <ThreadSafeQueue.h>
#include <TimeoutHelper.h>
#include <memory>

#ifdef HOY_DEBUG_QUEUE
#define DEBUG_PRINT(fmt, args...) Serial.printf(fmt, ##args)
#else
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif

class HoymilesRadio {
public:
Expand All @@ -14,11 +20,48 @@ class HoymilesRadio {

bool isIdle() const;
bool isQueueEmpty() const;
uint32_t getQueueSize() const;
bool isInitialized() const;

void removeCommands(InverterAbstract* inv);
uint8_t countSimilarCommands(std::shared_ptr<CommandAbstract> cmd);

void enqueCommand(std::shared_ptr<CommandAbstract> cmd)
{
DEBUG_PRINT("Queue size before: %ld\r\n", _commandQueue.size());
DEBUG_PRINT("Handling command %s with type %d\r\n", cmd.get()->getCommandName().c_str(), static_cast<uint8_t>(cmd.get()->getQueueInsertType()));
switch (cmd.get()->getQueueInsertType()) {
case QueueInsertType::RemoveOldest:
_commandQueue.removeDuplicatedEntries(cmd);
break;
case QueueInsertType::ReplaceExistent:
// Checks if the queue already contains a command like 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)
if (_commandQueue.countSimilarCommands(cmd) > 0) {
DEBUG_PRINT(" ... existing entry will be replaced\r\n");
_commandQueue.replaceEntries(cmd);
return;
}
break;
case QueueInsertType::RemoveNewest:
// Checks if the queue already contains a command like the new one
// and drops the new one. The new one will not be inserted.
if (_commandQueue.countSimilarCommands(cmd) > 0) {
DEBUG_PRINT(" ... new entry will be dropped\r\n");
return;
}
break;
case QueueInsertType::AllowMultiple:
// Dont do anything, just fall through and insert the command.
break;
}

// Push the command into the queue if we reach this position of the code
DEBUG_PRINT(" ... new entry will be appended\r\n");
_commandQueue.push(cmd);

DEBUG_PRINT("Queue size after: %ld\r\n", _commandQueue.size());
}

template <typename T>
Expand All @@ -38,7 +81,7 @@ class HoymilesRadio {
void handleReceivedPackage();

serial_u _dtuSerial;
ThreadSafeQueue<std::shared_ptr<CommandAbstract>> _commandQueue;
CommandQueue _commandQueue;
bool _isInitialized = false;
bool _busyFlag = false;

Expand Down
17 changes: 14 additions & 3 deletions lib/Hoymiles/src/commands/ActivePowerControlCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ ActivePowerControlCommand::ActivePowerControlCommand(InverterAbstract* inv, cons

String ActivePowerControlCommand::getCommandName() const
{
return "ActivePowerControl";
char buffer[30];
snprintf(buffer, sizeof(buffer), "ActivePowerControl (%02X)", getType());
return buffer;
}

bool ActivePowerControlCommand::areSameParameter(CommandAbstract* other)
{
return CommandAbstract::areSameParameter(other)
&& this->getType() == static_cast<ActivePowerControlCommand*>(other)->getType();
}

void ActivePowerControlCommand::setActivePowerLimit(const float limit, const PowerLimitControlType type)
Expand Down Expand Up @@ -79,7 +87,10 @@ bool ActivePowerControlCommand::handleResponse(const fragment_t fragment[], cons
}
}
_inv->SystemConfigPara()->setLastUpdateCommand(millis());
_inv->SystemConfigPara()->setLastLimitCommandSuccess(CMD_OK);
std::shared_ptr<ActivePowerControlCommand> cmd(std::shared_ptr<ActivePowerControlCommand>(), this);
if (_inv->getRadio()->countSimilarCommands(cmd) == 1) {
_inv->SystemConfigPara()->setLastLimitCommandSuccess(CMD_OK);
}
return true;
}

Expand All @@ -89,7 +100,7 @@ float ActivePowerControlCommand::getLimit() const
return l / 10;
}

PowerLimitControlType ActivePowerControlCommand::getType()
PowerLimitControlType ActivePowerControlCommand::getType() const
{
return (PowerLimitControlType)((static_cast<uint16_t>(_payload[14]) << 8) | _payload[15]);
}
Expand Down
4 changes: 3 additions & 1 deletion lib/Hoymiles/src/commands/ActivePowerControlCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ class ActivePowerControlCommand : public DevControlCommand {
explicit ActivePowerControlCommand(InverterAbstract* inv, const uint64_t router_address = 0);

virtual String getCommandName() const;
virtual QueueInsertType getQueueInsertType() const { return QueueInsertType::RemoveOldest; }
virtual bool areSameParameter(CommandAbstract* other);

virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
virtual void gotTimeout();

void setActivePowerLimit(const float limit, const PowerLimitControlType type = RelativNonPersistent);
float getLimit() const;
PowerLimitControlType getType();
PowerLimitControlType getType() const;
};
6 changes: 6 additions & 0 deletions lib/Hoymiles/src/commands/CommandAbstract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,9 @@ uint8_t CommandAbstract::getMaxRetransmitCount() const
{
return MAX_RETRANSMIT_COUNT;
}

bool CommandAbstract::areSameParameter(CommandAbstract* other)
{
return this->getCommandName() == other->getCommandName()
&& this->_targetAddress == other->getTargetAddress();
}
16 changes: 16 additions & 0 deletions lib/Hoymiles/src/commands/CommandAbstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@

class InverterAbstract;

enum class QueueInsertType {
AllowMultiple,
// Remove from beginning of the queue
RemoveOldest,

// Don't insert command if it already exist
RemoveNewest,

// Replace the existing entry in the queue by the one to be added
ReplaceExistent,
};

class CommandAbstract {
public:
explicit CommandAbstract(InverterAbstract* inv, const uint64_t router_address = 0);
Expand Down Expand Up @@ -46,6 +58,10 @@ class CommandAbstract {
// Sets the amount how often a missing fragment is re-requested if it was not available
virtual uint8_t getMaxRetransmitCount() const;

// Returns whether multiple instances of this command are allowed in the command queue.
virtual QueueInsertType getQueueInsertType() const { return QueueInsertType::RemoveNewest; }
virtual bool areSameParameter(CommandAbstract* other);

protected:
uint8_t _payload[RF_LEN];
uint8_t _payload_size;
Expand Down
1 change: 1 addition & 0 deletions lib/Hoymiles/src/commands/PowerControlCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class PowerControlCommand : public DevControlCommand {
explicit PowerControlCommand(InverterAbstract* inv, const uint64_t router_address = 0);

virtual String getCommandName() const;
virtual QueueInsertType getQueueInsertType() const { return QueueInsertType::AllowMultiple; }

virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
virtual void gotTimeout();
Expand Down
4 changes: 3 additions & 1 deletion lib/Hoymiles/src/inverters/HERF_1CH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ static const channelMetaData_t channelMetaData[] = {
};

HERF_1CH::HERF_1CH(HoymilesRadio* radio, const uint64_t serial)
: HM_Abstract(radio, serial) {};
: HM_Abstract(radio, serial)
{
}

bool HERF_1CH::isValidSerial(const uint64_t serial)
{
Expand Down
6 changes: 4 additions & 2 deletions lib/Hoymiles/src/inverters/HERF_2CH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ static const channelMetaData_t channelMetaData[] = {
};

HERF_2CH::HERF_2CH(HoymilesRadio* radio, const uint64_t serial)
: HM_Abstract(radio, serial) {};
: HM_Abstract(radio, serial)
{
}

bool HERF_2CH::isValidSerial(const uint64_t serial)
{
Expand All @@ -53,7 +55,7 @@ bool HERF_2CH::isValidSerial(const uint64_t serial)

String HERF_2CH::typeName() const
{
return "HERF-800-2T";
return "HERF-600/800-2T";
}

const byteAssign_t* HERF_2CH::getByteAssignment() const
Expand Down
4 changes: 3 additions & 1 deletion lib/Hoymiles/src/inverters/HERF_4CH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include "HERF_4CH.h"

HERF_4CH::HERF_4CH(HoymilesRadio* radio, const uint64_t serial)
: HM_4CH(radio, serial) {};
: HM_4CH(radio, serial)
{
}

bool HERF_4CH::isValidSerial(const uint64_t serial)
{
Expand Down
4 changes: 3 additions & 1 deletion lib/Hoymiles/src/inverters/HMS_1CH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ static const channelMetaData_t channelMetaData[] = {
};

HMS_1CH::HMS_1CH(HoymilesRadio* radio, const uint64_t serial)
: HMS_Abstract(radio, serial) {};
: HMS_Abstract(radio, serial)
{
}

bool HMS_1CH::isValidSerial(const uint64_t serial)
{
Expand Down
8 changes: 5 additions & 3 deletions lib/Hoymiles/src/inverters/HMS_1CHv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@ static const channelMetaData_t channelMetaData[] = {
};

HMS_1CHv2::HMS_1CHv2(HoymilesRadio* radio, const uint64_t serial)
: HMS_Abstract(radio, serial) {};
: HMS_Abstract(radio, serial)
{
}

bool HMS_1CHv2::isValidSerial(const uint64_t serial)
{
// serial >= 0x112500000000 && serial <= 0x1125ffffffff
uint16_t preSerial = (serial >> 32) & 0xffff;
return preSerial == 0x1125;
return preSerial == 0x1125 || preSerial == 0x1400;
}

String HMS_1CHv2::typeName() const
{
return "HMS-500-1T v2";
return "HMS-450/500-1T v2";
}

const byteAssign_t* HMS_1CHv2::getByteAssignment() const
Expand Down
Loading

0 comments on commit 3fc91ee

Please sign in to comment.