Feature: Allow setting of the Reachable Threshold per inverter
This commit is contained in:
parent
c5f9f460cd
commit
2c41be106e
@ -45,6 +45,7 @@ struct INVERTER_CONFIG_T {
|
||||
bool Poll_Enable_Night;
|
||||
bool Command_Enable;
|
||||
bool Command_Enable_Night;
|
||||
uint8_t ReachableThreshold;
|
||||
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
|
||||
};
|
||||
|
||||
|
||||
@ -94,4 +94,6 @@
|
||||
#define DISPLAY_SCREENSAVER true
|
||||
#define DISPLAY_ROTATION 2U
|
||||
#define DISPLAY_CONTRAST 60U
|
||||
#define DISPLAY_LANGUAGE 0U
|
||||
#define DISPLAY_LANGUAGE 0U
|
||||
|
||||
#define REACHABLE_THRESHOLD 2U
|
||||
@ -73,7 +73,7 @@ bool InverterAbstract::isProducing()
|
||||
|
||||
bool InverterAbstract::isReachable()
|
||||
{
|
||||
return _enablePolling && Statistics()->getRxFailureCount() <= MAX_ONLINE_FAILURE_COUNT;
|
||||
return _enablePolling && Statistics()->getRxFailureCount() <= _reachableThreshold;
|
||||
}
|
||||
|
||||
void InverterAbstract::setEnablePolling(bool enabled)
|
||||
@ -96,6 +96,16 @@ bool InverterAbstract::getEnableCommands()
|
||||
return _enableCommands;
|
||||
}
|
||||
|
||||
void InverterAbstract::setReachableThreshold(uint8_t threshold)
|
||||
{
|
||||
_reachableThreshold = threshold;
|
||||
}
|
||||
|
||||
uint8_t InverterAbstract::getReachableThreshold()
|
||||
{
|
||||
return _reachableThreshold;
|
||||
}
|
||||
|
||||
bool InverterAbstract::sendChangeChannelRequest()
|
||||
{
|
||||
return false;
|
||||
|
||||
@ -24,7 +24,6 @@ enum {
|
||||
};
|
||||
|
||||
#define MAX_RF_FRAGMENT_COUNT 13
|
||||
#define MAX_ONLINE_FAILURE_COUNT 2
|
||||
|
||||
class CommandAbstract;
|
||||
|
||||
@ -49,6 +48,9 @@ public:
|
||||
void setEnableCommands(bool enabled);
|
||||
bool getEnableCommands();
|
||||
|
||||
void setReachableThreshold(uint8_t threshold);
|
||||
uint8_t getReachableThreshold();
|
||||
|
||||
void clearRxFragmentBuffer();
|
||||
void addRxFragment(uint8_t fragment[], uint8_t len);
|
||||
uint8_t verifyAllFragments(CommandAbstract* cmd);
|
||||
@ -87,6 +89,8 @@ private:
|
||||
bool _enablePolling = true;
|
||||
bool _enableCommands = true;
|
||||
|
||||
uint8_t _reachableThreshold = 3;
|
||||
|
||||
std::unique_ptr<AlarmLogParser> _alarmLogParser;
|
||||
std::unique_ptr<DevInfoParser> _devInfoParser;
|
||||
std::unique_ptr<PowerCommandParser> _powerCommandParser;
|
||||
|
||||
@ -110,6 +110,7 @@ bool ConfigurationClass::write()
|
||||
inv["poll_enable_night"] = config.Inverter[i].Poll_Enable_Night;
|
||||
inv["command_enable"] = config.Inverter[i].Command_Enable;
|
||||
inv["command_enable_night"] = config.Inverter[i].Command_Enable_Night;
|
||||
inv["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
||||
|
||||
JsonArray channel = inv.createNestedArray("channel");
|
||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||
@ -258,6 +259,7 @@ bool ConfigurationClass::read()
|
||||
config.Inverter[i].Poll_Enable_Night = inv["poll_enable_night"] | true;
|
||||
config.Inverter[i].Command_Enable = inv["command_enable"] | true;
|
||||
config.Inverter[i].Command_Enable_Night = inv["command_enable_night"] | true;
|
||||
config.Inverter[i].ReachableThreshold = inv["reachable_threshold"] | REACHABLE_THRESHOLD;
|
||||
|
||||
JsonArray channel = inv["channel"];
|
||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||
|
||||
@ -71,6 +71,7 @@ void InverterSettingsClass::init()
|
||||
config.Inverter[i].Serial);
|
||||
|
||||
if (inv != nullptr) {
|
||||
inv->setReachableThreshold(config.Inverter[i].ReachableThreshold);
|
||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||
inv->Statistics()->setStringMaxPower(c, config.Inverter[i].channel[c].MaxChannelPower);
|
||||
inv->Statistics()->setChannelFieldOffset(TYPE_DC, static_cast<ChannelNum_t>(c), FLD_YT, config.Inverter[i].channel[c].YieldTotalOffset);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "MqttHandleHass.h"
|
||||
#include "WebApi.h"
|
||||
#include "WebApi_errors.h"
|
||||
#include "defaults.h"
|
||||
#include "helper.h"
|
||||
#include <AsyncJson.h>
|
||||
#include <Hoymiles.h>
|
||||
@ -57,6 +58,7 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
|
||||
obj["poll_enable_night"] = config.Inverter[i].Poll_Enable_Night;
|
||||
obj["command_enable"] = config.Inverter[i].Command_Enable;
|
||||
obj["command_enable_night"] = config.Inverter[i].Command_Enable_Night;
|
||||
obj["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
||||
|
||||
auto inv = Hoymiles.getInverterBySerial(config.Inverter[i].Serial);
|
||||
uint8_t max_channels;
|
||||
@ -281,6 +283,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
inverter.Poll_Enable_Night = root["poll_enable_night"] | true;
|
||||
inverter.Command_Enable = root["command_enable"] | true;
|
||||
inverter.Command_Enable_Night = root["command_enable_night"] | true;
|
||||
inverter.ReachableThreshold = root["reachable_threshold"] | REACHABLE_THRESHOLD;
|
||||
|
||||
arrayCount++;
|
||||
}
|
||||
@ -311,6 +314,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
if (inv != nullptr) {
|
||||
inv->setEnablePolling(inverter.Poll_Enable);
|
||||
inv->setEnableCommands(inverter.Command_Enable);
|
||||
inv->setReachableThreshold(inverter.ReachableThreshold);
|
||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||
inv->Statistics()->setStringMaxPower(c, inverter.channel[c].MaxChannelPower);
|
||||
inv->Statistics()->setChannelFieldOffset(TYPE_DC, static_cast<ChannelNum_t>(c), FLD_YT, inverter.channel[c].YieldTotalOffset);
|
||||
|
||||
@ -454,6 +454,7 @@
|
||||
"EditInverter": "Wechselrichter bearbeiten",
|
||||
"General": "Allgemein",
|
||||
"String": "String",
|
||||
"Advanced": "Erweitert",
|
||||
"InverterSerial": "Wechselrichter Seriennummer:",
|
||||
"InverterName": "Wechselrichter Name:",
|
||||
"InverterNameHint": "Hier kann ein eigener Namen für den Wechselrichter angeben werden.",
|
||||
@ -469,6 +470,8 @@
|
||||
"StringYtOffset": "Ertragsversatz String {num}:",
|
||||
"StringYtOffsetHint": "Dieser Offset wird beim Auslesen des Gesamtertragswertes des Wechselrichters angewendet. Damit kann der Gesamtertrag des Wechselrichters auf Null gesetzt werden, wenn ein gebrauchter Wechselrichter verwendet wird.",
|
||||
"InverterHint": "*) Geben Sie die W<sub>p</sub> des Ports ein, um die Einstrahlung zu errechnen.",
|
||||
"ReachableThreshold": "Erreichbarkeit Schwellenwert:",
|
||||
"ReachableThresholdHint": "Legt fest, wie viele Anfragen fehlschlagen dürfen, bis der Wechselrichter als unerreichbar eingestuft wird.",
|
||||
"Cancel": "@:maintenancereboot.Cancel",
|
||||
"Save": "@:dtuadmin.Save",
|
||||
"DeleteMsg": "Soll der Wechselrichter \"{name}\" mit der Seriennummer {serial} wirklich gelöscht werden?",
|
||||
|
||||
@ -454,6 +454,7 @@
|
||||
"EditInverter": "Edit inverter",
|
||||
"General": "General",
|
||||
"String": "String",
|
||||
"Advanced": "Advanced",
|
||||
"InverterSerial": "Inverter Serial:",
|
||||
"InverterName": "Inverter Name:",
|
||||
"InverterNameHint": "Here you can specify a custom name for your inverter.",
|
||||
@ -469,6 +470,8 @@
|
||||
"StringYtOffset": "Yield total offset string {num}:",
|
||||
"StringYtOffsetHint": "This offset is applied the read yield total value from the inverter. This can be used to set the yield total of the inverter to zero if a used inverter is used. But you can still try polling data.",
|
||||
"InverterHint": "*) Enter the W<sub>p</sub> of the channel to calculate irradiation.",
|
||||
"ReachableThreshold": "Reachable Threshold:",
|
||||
"ReachableThresholdHint": "Defines how many requests are allowed to fail until the inverter is treated is not reachable.",
|
||||
"Cancel": "@:maintenancereboot.Cancel",
|
||||
"Save": "@:dtuadmin.Save",
|
||||
"DeleteMsg": "Are you sure you want to delete the inverter \"{name}\" with serial number {serial}?",
|
||||
|
||||
@ -454,6 +454,7 @@
|
||||
"EditInverter": "Modifier l'onduleur",
|
||||
"General": "Général",
|
||||
"String": "Ligne",
|
||||
"Advanced": "Advanced",
|
||||
"InverterSerial": "Numéro de série de l'onduleur",
|
||||
"InverterName": "Nom de l'onduleur :",
|
||||
"InverterNameHint": "Ici, vous pouvez spécifier un nom personnalisé pour votre onduleur.",
|
||||
@ -469,6 +470,8 @@
|
||||
"StringYtOffset": "Décalage du rendement total de la ligne {num} :",
|
||||
"StringYtOffsetHint": "Ce décalage est appliqué à la valeur de rendement total lue sur le variateur. Il peut être utilisé pour mettre le rendement total du variateur à zéro si un variateur usagé est utilisé.",
|
||||
"InverterHint": "*) Entrez le W<sub>p</sub> du canal pour calculer l'irradiation.",
|
||||
"ReachableThreshold": "Reachable Threshold:",
|
||||
"ReachableThresholdHint": "Defines how many requests are allowed to fail until the inverter is treated is not reachable.",
|
||||
"Cancel": "@:maintenancereboot.Cancel",
|
||||
"Save": "@:dtuadmin.Save",
|
||||
"DeleteMsg": "Êtes-vous sûr de vouloir supprimer l'onduleur \"{name}\" avec le numéro de série \"{serial}\" ?",
|
||||
|
||||
@ -88,6 +88,8 @@
|
||||
}}</button>
|
||||
<button class="nav-link" id="nav-string-tab" data-bs-toggle="tab" data-bs-target="#nav-string"
|
||||
type="button" role="tab" aria-controls="nav-string">{{ $t('inverteradmin.String') }}</button>
|
||||
<button class="nav-link" id="nav-advanced-tab" data-bs-toggle="tab" data-bs-target="#nav-advanced"
|
||||
type="button" role="tab" aria-controls="nav-advanced">{{ $t('inverteradmin.Advanced') }}</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
@ -174,6 +176,13 @@
|
||||
<div :id="`inverter-customizer`" class="form-text" v-html="$t('inverteradmin.InverterHint')">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade show" id="nav-advanced" role="tabpanel" aria-labelledby="nav-advanced-tab" tabindex="0">
|
||||
<InputElement :label="$t('inverteradmin.ReachableThreshold')"
|
||||
v-model="selectedInverterData.reachable_threshold"
|
||||
type="number" min="1" max="100"
|
||||
:tooltip="$t('inverteradmin.ReachableThresholdHint')" wide />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -247,6 +256,7 @@ declare interface Inverter {
|
||||
poll_enable_night: boolean;
|
||||
command_enable: boolean;
|
||||
command_enable_night: boolean;
|
||||
reachable_threshold: number;
|
||||
channel: Array<Channel>;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user