Merge branch 'tbnobody:master' into master
This commit is contained in:
commit
7d1a3c6af9
24
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
24
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -5,11 +5,18 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: >
|
value: >
|
||||||
### ✋ **This is bug tracker, not a support forum**
|
### ⚠️ Please remember: issues are for *bugs*
|
||||||
|
That is, something you believe affects every single user of OpenDTU, not just you. If you're not sure, start with one of the other options below.
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
#### Have a question? 👉 [Start a new discussion](https://github.com/tbnobody/OpenDTU/discussions/new) or [ask in chat](https://discord.gg/WzhxEY62mB).
|
||||||
|
|
||||||
If something isn't working right, you have questions or need help, [**get in touch on the Discussions**](https://github.com/tbnobody/OpenDTU/discussions).
|
#### Before opening an issue, please double check:
|
||||||
|
|
||||||
Please quickly search existing issues first before submitting a bug.
|
- [Documentation](https://www.opendtu.solar).
|
||||||
|
- [The FAQs](https://www.opendtu.solar/firmware/faq/).
|
||||||
|
- [Existing issues and discussions](https://github.com/tbnobody/OpenDTU/search?q=&type=issues).
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: what-happened
|
id: what-happened
|
||||||
attributes:
|
attributes:
|
||||||
@ -66,3 +73,14 @@ body:
|
|||||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
- type: checkboxes
|
||||||
|
id: required-checks
|
||||||
|
attributes:
|
||||||
|
label: Please confirm the following
|
||||||
|
options:
|
||||||
|
- label: I believe this issue is a bug that affects all users of OpenDTU, not something specific to my installation.
|
||||||
|
required: true
|
||||||
|
- label: I have already searched for relevant existing issues and discussions before opening this report.
|
||||||
|
required: true
|
||||||
|
- label: I have updated the title field above with a concise description.
|
||||||
|
required: true
|
||||||
|
|||||||
@ -47,6 +47,7 @@ struct INVERTER_CONFIG_T {
|
|||||||
uint8_t ReachableThreshold;
|
uint8_t ReachableThreshold;
|
||||||
bool ZeroRuntimeDataIfUnrechable;
|
bool ZeroRuntimeDataIfUnrechable;
|
||||||
bool ZeroYieldDayOnMidnight;
|
bool ZeroYieldDayOnMidnight;
|
||||||
|
bool ClearEventlogOnMidnight;
|
||||||
bool YieldDayCorrection;
|
bool YieldDayCorrection;
|
||||||
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
|
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,6 +13,9 @@ public:
|
|||||||
|
|
||||||
static String getTopic(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
static String getTopic(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
||||||
|
|
||||||
|
void subscribeTopics();
|
||||||
|
void unsubscribeTopics();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loop();
|
void loop();
|
||||||
void publishField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
void publishField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
||||||
|
|||||||
51
lib/CpuTemperature/src/CpuTemperature.cpp
Normal file
51
lib/CpuTemperature/src/CpuTemperature.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Thomas Basler and others
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CpuTemperature.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
// there is no official API available on the original ESP32
|
||||||
|
extern "C" {
|
||||||
|
uint8_t temprature_sens_read();
|
||||||
|
}
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
#include "driver/temp_sensor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CpuTemperatureClass CpuTemperature;
|
||||||
|
|
||||||
|
float CpuTemperatureClass::read()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
|
||||||
|
float temperature = NAN;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
uint8_t raw = temprature_sens_read();
|
||||||
|
ESP_LOGV(TAG, "Raw temperature value: %d", raw);
|
||||||
|
temperature = (raw - 32) / 1.8f;
|
||||||
|
success = (raw != 128);
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
|
||||||
|
temp_sensor_set_config(tsens);
|
||||||
|
temp_sensor_start();
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 3))
|
||||||
|
#error \
|
||||||
|
"ESP32-S3 internal temperature sensor requires ESP IDF V4.4.3 or higher. See https://github.com/esphome/issues/issues/4271"
|
||||||
|
#endif
|
||||||
|
esp_err_t result = temp_sensor_read_celsius(&temperature);
|
||||||
|
temp_sensor_stop();
|
||||||
|
success = (result == ESP_OK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (success && std::isfinite(temperature)) {
|
||||||
|
return temperature;
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Ignoring invalid temperature (success=%d, value=%.1f)", success, temperature);
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
lib/CpuTemperature/src/CpuTemperature.h
Normal file
14
lib/CpuTemperature/src/CpuTemperature.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
class CpuTemperatureClass {
|
||||||
|
public:
|
||||||
|
float read();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CpuTemperatureClass CpuTemperature;
|
||||||
@ -141,6 +141,9 @@ void HoymilesClass::loop()
|
|||||||
if (inv->getZeroYieldDayOnMidnight()) {
|
if (inv->getZeroYieldDayOnMidnight()) {
|
||||||
inv->Statistics()->zeroDailyData();
|
inv->Statistics()->zeroDailyData();
|
||||||
}
|
}
|
||||||
|
if (inv->getClearEventlogOnMidnight()) {
|
||||||
|
inv->EventLog()->clearBuffer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastWeekDay = currentWeekDay;
|
lastWeekDay = currentWeekDay;
|
||||||
|
|||||||
@ -22,9 +22,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::shared_ptr<T> prepareCommand()
|
std::shared_ptr<T> prepareCommand(InverterAbstract* inv)
|
||||||
{
|
{
|
||||||
return std::make_shared<T>();
|
return std::make_shared<T>(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -25,8 +25,8 @@ ID Target Addr Source Addr Cmd SCmd ? Limit Type CRC16 CRC8
|
|||||||
|
|
||||||
#define CRC_SIZE 6
|
#define CRC_SIZE 6
|
||||||
|
|
||||||
ActivePowerControlCommand::ActivePowerControlCommand(const uint64_t target_address, const uint64_t router_address)
|
ActivePowerControlCommand::ActivePowerControlCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: DevControlCommand(target_address, router_address)
|
: DevControlCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[10] = 0x0b;
|
_payload[10] = 0x0b;
|
||||||
_payload[11] = 0x00;
|
_payload[11] = 0x00;
|
||||||
@ -62,24 +62,24 @@ void ActivePowerControlCommand::setActivePowerLimit(const float limit, const Pow
|
|||||||
udpateCRC(CRC_SIZE);
|
udpateCRC(CRC_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActivePowerControlCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool ActivePowerControlCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
if (!DevControlCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!DevControlCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((getType() == PowerLimitControlType::RelativNonPersistent) || (getType() == PowerLimitControlType::RelativPersistent)) {
|
if ((getType() == PowerLimitControlType::RelativNonPersistent) || (getType() == PowerLimitControlType::RelativPersistent)) {
|
||||||
inverter.SystemConfigPara()->setLimitPercent(getLimit());
|
_inv->SystemConfigPara()->setLimitPercent(getLimit());
|
||||||
} else {
|
} else {
|
||||||
const uint16_t max_power = inverter.DevInfo()->getMaxPower();
|
const uint16_t max_power = _inv->DevInfo()->getMaxPower();
|
||||||
if (max_power > 0) {
|
if (max_power > 0) {
|
||||||
inverter.SystemConfigPara()->setLimitPercent(static_cast<float>(getLimit()) / max_power * 100);
|
_inv->SystemConfigPara()->setLimitPercent(static_cast<float>(getLimit()) / max_power * 100);
|
||||||
} else {
|
} else {
|
||||||
// TODO(tbnobody): Not implemented yet because we only can publish the percentage value
|
// TODO(tbnobody): Not implemented yet because we only can publish the percentage value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inverter.SystemConfigPara()->setLastUpdateCommand(millis());
|
_inv->SystemConfigPara()->setLastUpdateCommand(millis());
|
||||||
inverter.SystemConfigPara()->setLastLimitCommandSuccess(CMD_OK);
|
_inv->SystemConfigPara()->setLastLimitCommandSuccess(CMD_OK);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ PowerLimitControlType ActivePowerControlCommand::getType()
|
|||||||
return (PowerLimitControlType)(((uint16_t)_payload[14] << 8) | _payload[15]);
|
return (PowerLimitControlType)(((uint16_t)_payload[14] << 8) | _payload[15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivePowerControlCommand::gotTimeout(InverterAbstract& inverter)
|
void ActivePowerControlCommand::gotTimeout()
|
||||||
{
|
{
|
||||||
inverter.SystemConfigPara()->setLastLimitCommandSuccess(CMD_NOK);
|
_inv->SystemConfigPara()->setLastLimitCommandSuccess(CMD_NOK);
|
||||||
}
|
}
|
||||||
@ -12,12 +12,12 @@ typedef enum { // ToDo: to be verified by field tests
|
|||||||
|
|
||||||
class ActivePowerControlCommand : public DevControlCommand {
|
class ActivePowerControlCommand : public DevControlCommand {
|
||||||
public:
|
public:
|
||||||
explicit ActivePowerControlCommand(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit ActivePowerControlCommand(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
|
|
||||||
void setActivePowerLimit(const float limit, const PowerLimitControlType type = RelativNonPersistent);
|
void setActivePowerLimit(const float limit, const PowerLimitControlType type = RelativNonPersistent);
|
||||||
float getLimit() const;
|
float getLimit() const;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -23,8 +23,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap AlarmId Pa
|
|||||||
#include "AlarmDataCommand.h"
|
#include "AlarmDataCommand.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
AlarmDataCommand::AlarmDataCommand(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
AlarmDataCommand::AlarmDataCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x11);
|
setDataType(0x11);
|
||||||
@ -36,28 +36,28 @@ String AlarmDataCommand::getCommandName() const
|
|||||||
return "AlarmData";
|
return "AlarmData";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AlarmDataCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool AlarmDataCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.EventLog()->beginAppendFragment();
|
_inv->EventLog()->beginAppendFragment();
|
||||||
inverter.EventLog()->clearBuffer();
|
_inv->EventLog()->clearBuffer();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.EventLog()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
_inv->EventLog()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.EventLog()->endAppendFragment();
|
_inv->EventLog()->endAppendFragment();
|
||||||
inverter.EventLog()->setLastAlarmRequestSuccess(CMD_OK);
|
_inv->EventLog()->setLastAlarmRequestSuccess(CMD_OK);
|
||||||
inverter.EventLog()->setLastUpdate(millis());
|
_inv->EventLog()->setLastUpdate(millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlarmDataCommand::gotTimeout(InverterAbstract& inverter)
|
void AlarmDataCommand::gotTimeout()
|
||||||
{
|
{
|
||||||
inverter.EventLog()->setLastAlarmRequestSuccess(CMD_NOK);
|
_inv->EventLog()->setLastAlarmRequestSuccess(CMD_NOK);
|
||||||
}
|
}
|
||||||
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class AlarmDataCommand : public MultiDataCommand {
|
class AlarmDataCommand : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit AlarmDataCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit AlarmDataCommand(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
};
|
};
|
||||||
@ -19,8 +19,8 @@ ID Target Addr Source Addr ? ? ? CH ? CRC8
|
|||||||
*/
|
*/
|
||||||
#include "ChannelChangeCommand.h"
|
#include "ChannelChangeCommand.h"
|
||||||
|
|
||||||
ChannelChangeCommand::ChannelChangeCommand(const uint64_t target_address, const uint64_t router_address, const uint8_t channel)
|
ChannelChangeCommand::ChannelChangeCommand(InverterAbstract* inv, const uint64_t router_address, const uint8_t channel)
|
||||||
: CommandAbstract(target_address, router_address)
|
: CommandAbstract(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[0] = 0x56;
|
_payload[0] = 0x56;
|
||||||
_payload[13] = 0x14;
|
_payload[13] = 0x14;
|
||||||
@ -67,7 +67,7 @@ void ChannelChangeCommand::setCountryMode(const CountryModeId_t mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelChangeCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool ChannelChangeCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
class ChannelChangeCommand : public CommandAbstract {
|
class ChannelChangeCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit ChannelChangeCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const uint8_t channel = 0);
|
explicit ChannelChangeCommand(InverterAbstract* inv, const uint64_t router_address = 0, const uint8_t channel = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ public:
|
|||||||
|
|
||||||
void setCountryMode(const CountryModeId_t mode);
|
void setCountryMode(const CountryModeId_t mode);
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
|
|
||||||
virtual uint8_t getMaxResendCount();
|
virtual uint8_t getMaxResendCount();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,13 +29,16 @@ Source Address: 80 12 23 04
|
|||||||
#include "CommandAbstract.h"
|
#include "CommandAbstract.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "../inverters/InverterAbstract.h"
|
||||||
|
|
||||||
CommandAbstract::CommandAbstract(const uint64_t target_address, const uint64_t router_address)
|
CommandAbstract::CommandAbstract(InverterAbstract* inv, const uint64_t router_address)
|
||||||
{
|
{
|
||||||
memset(_payload, 0, RF_LEN);
|
memset(_payload, 0, RF_LEN);
|
||||||
_payload_size = 0;
|
_payload_size = 0;
|
||||||
|
|
||||||
setTargetAddress(target_address);
|
_inv = inv;
|
||||||
|
|
||||||
|
setTargetAddress(_inv->serial());
|
||||||
setRouterAddress(router_address);
|
setRouterAddress(router_address);
|
||||||
setSendCount(0);
|
setSendCount(0);
|
||||||
setTimeout(0);
|
setTimeout(0);
|
||||||
@ -122,7 +125,7 @@ void CommandAbstract::convertSerialToPacketId(uint8_t buffer[], const uint64_t s
|
|||||||
buffer[0] = s.b[3];
|
buffer[0] = s.b[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandAbstract::gotTimeout(InverterAbstract& inverter)
|
void CommandAbstract::gotTimeout()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class InverterAbstract;
|
|||||||
|
|
||||||
class CommandAbstract {
|
class CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit CommandAbstract(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit CommandAbstract(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
virtual ~CommandAbstract() {};
|
virtual ~CommandAbstract() {};
|
||||||
|
|
||||||
const uint8_t* getDataPayload();
|
const uint8_t* getDataPayload();
|
||||||
@ -21,7 +21,6 @@ public:
|
|||||||
|
|
||||||
uint8_t getDataSize() const;
|
uint8_t getDataSize() const;
|
||||||
|
|
||||||
void setTargetAddress(const uint64_t address);
|
|
||||||
uint64_t getTargetAddress() const;
|
uint64_t getTargetAddress() const;
|
||||||
|
|
||||||
void setRouterAddress(const uint64_t address);
|
void setRouterAddress(const uint64_t address);
|
||||||
@ -38,8 +37,8 @@ public:
|
|||||||
|
|
||||||
virtual CommandAbstract* getRequestFrameCommand(const uint8_t frame_no);
|
virtual CommandAbstract* getRequestFrameCommand(const uint8_t frame_no);
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id) = 0;
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id) = 0;
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
|
|
||||||
// Sets the amount how often the specific command is resent if all fragments where missing
|
// Sets the amount how often the specific command is resent if all fragments where missing
|
||||||
virtual uint8_t getMaxResendCount() const;
|
virtual uint8_t getMaxResendCount() const;
|
||||||
@ -56,6 +55,9 @@ protected:
|
|||||||
uint64_t _targetAddress;
|
uint64_t _targetAddress;
|
||||||
uint64_t _routerAddress;
|
uint64_t _routerAddress;
|
||||||
|
|
||||||
|
InverterAbstract* _inv;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setTargetAddress(const uint64_t address);
|
||||||
static void convertSerialToPacketId(uint8_t buffer[], const uint64_t serial);
|
static void convertSerialToPacketId(uint8_t buffer[], const uint64_t serial);
|
||||||
};
|
};
|
||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -23,8 +23,8 @@ ID Target Addr Source Addr Cmd Payload CRC16 CRC8
|
|||||||
#include "DevControlCommand.h"
|
#include "DevControlCommand.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
DevControlCommand::DevControlCommand(const uint64_t target_address, const uint64_t router_address)
|
DevControlCommand::DevControlCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: CommandAbstract(target_address, router_address)
|
: CommandAbstract(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[0] = 0x51;
|
_payload[0] = 0x51;
|
||||||
_payload[9] = 0x81;
|
_payload[9] = 0x81;
|
||||||
@ -39,7 +39,7 @@ void DevControlCommand::udpateCRC(const uint8_t len)
|
|||||||
_payload[10 + len + 1] = (uint8_t)(crc);
|
_payload[10 + len + 1] = (uint8_t)(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DevControlCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool DevControlCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
if (fragment[i].mainCmd != (_payload[0] | 0x80)) {
|
if (fragment[i].mainCmd != (_payload[0] | 0x80)) {
|
||||||
|
|||||||
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class DevControlCommand : public CommandAbstract {
|
class DevControlCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit DevControlCommand(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit DevControlCommand(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void udpateCRC(const uint8_t len);
|
void udpateCRC(const uint8_t len);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -21,8 +21,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "DevInfoAllCommand.h"
|
#include "DevInfoAllCommand.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
DevInfoAllCommand::DevInfoAllCommand(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
DevInfoAllCommand::DevInfoAllCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x01);
|
setDataType(0x01);
|
||||||
@ -34,22 +34,22 @@ String DevInfoAllCommand::getCommandName() const
|
|||||||
return "DevInfoAll";
|
return "DevInfoAll";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DevInfoAllCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool DevInfoAllCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.DevInfo()->beginAppendFragment();
|
_inv->DevInfo()->beginAppendFragment();
|
||||||
inverter.DevInfo()->clearBufferAll();
|
_inv->DevInfo()->clearBufferAll();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.DevInfo()->appendFragmentAll(offs, fragment[i].fragment, fragment[i].len);
|
_inv->DevInfo()->appendFragmentAll(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.DevInfo()->endAppendFragment();
|
_inv->DevInfo()->endAppendFragment();
|
||||||
inverter.DevInfo()->setLastUpdateAll(millis());
|
_inv->DevInfo()->setLastUpdateAll(millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class DevInfoAllCommand : public MultiDataCommand {
|
class DevInfoAllCommand : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit DevInfoAllCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit DevInfoAllCommand(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -21,8 +21,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "DevInfoSimpleCommand.h"
|
#include "DevInfoSimpleCommand.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
DevInfoSimpleCommand::DevInfoSimpleCommand(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
DevInfoSimpleCommand::DevInfoSimpleCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x00);
|
setDataType(0x00);
|
||||||
@ -34,22 +34,22 @@ String DevInfoSimpleCommand::getCommandName() const
|
|||||||
return "DevInfoSimple";
|
return "DevInfoSimple";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DevInfoSimpleCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool DevInfoSimpleCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.DevInfo()->beginAppendFragment();
|
_inv->DevInfo()->beginAppendFragment();
|
||||||
inverter.DevInfo()->clearBufferSimple();
|
_inv->DevInfo()->clearBufferSimple();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.DevInfo()->appendFragmentSimple(offs, fragment[i].fragment, fragment[i].len);
|
_inv->DevInfo()->appendFragmentSimple(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.DevInfo()->endAppendFragment();
|
_inv->DevInfo()->endAppendFragment();
|
||||||
inverter.DevInfo()->setLastUpdateSimple(millis());
|
_inv->DevInfo()->setLastUpdateSimple(millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class DevInfoSimpleCommand : public MultiDataCommand {
|
class DevInfoSimpleCommand : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit DevInfoSimpleCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit DevInfoSimpleCommand(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,8 +22,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
GridOnProFilePara::GridOnProFilePara(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
GridOnProFilePara::GridOnProFilePara(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x02);
|
setDataType(0x02);
|
||||||
@ -35,22 +35,22 @@ String GridOnProFilePara::getCommandName() const
|
|||||||
return "GridOnProFilePara";
|
return "GridOnProFilePara";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GridOnProFilePara::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool GridOnProFilePara::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.GridProfile()->beginAppendFragment();
|
_inv->GridProfile()->beginAppendFragment();
|
||||||
inverter.GridProfile()->clearBuffer();
|
_inv->GridProfile()->clearBuffer();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.GridProfile()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
_inv->GridProfile()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.GridProfile()->endAppendFragment();
|
_inv->GridProfile()->endAppendFragment();
|
||||||
inverter.GridProfile()->setLastUpdate(millis());
|
_inv->GridProfile()->setLastUpdate(millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class GridOnProFilePara : public MultiDataCommand {
|
class GridOnProFilePara : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit GridOnProFilePara(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit GridOnProFilePara(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -28,8 +28,9 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "MultiDataCommand.h"
|
#include "MultiDataCommand.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
MultiDataCommand::MultiDataCommand(const uint64_t target_address, const uint64_t router_address, const uint8_t data_type, const time_t time)
|
MultiDataCommand::MultiDataCommand(InverterAbstract* inv, const uint64_t router_address, const uint8_t data_type, const time_t time)
|
||||||
: CommandAbstract(target_address, router_address)
|
: CommandAbstract(inv, router_address)
|
||||||
|
, _cmdRequestFrame(inv)
|
||||||
{
|
{
|
||||||
_payload[0] = 0x15;
|
_payload[0] = 0x15;
|
||||||
_payload[9] = 0x80;
|
_payload[9] = 0x80;
|
||||||
@ -79,13 +80,12 @@ time_t MultiDataCommand::getTime() const
|
|||||||
|
|
||||||
CommandAbstract* MultiDataCommand::getRequestFrameCommand(const uint8_t frame_no)
|
CommandAbstract* MultiDataCommand::getRequestFrameCommand(const uint8_t frame_no)
|
||||||
{
|
{
|
||||||
_cmdRequestFrame.setTargetAddress(getTargetAddress());
|
|
||||||
_cmdRequestFrame.setFrameNo(frame_no);
|
_cmdRequestFrame.setFrameNo(frame_no);
|
||||||
|
|
||||||
return &_cmdRequestFrame;
|
return &_cmdRequestFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiDataCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool MultiDataCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// All fragments are available --> Check CRC
|
// All fragments are available --> Check CRC
|
||||||
uint16_t crc = 0xffff, crcRcv = 0;
|
uint16_t crc = 0xffff, crcRcv = 0;
|
||||||
|
|||||||
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
class MultiDataCommand : public CommandAbstract {
|
class MultiDataCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit MultiDataCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const uint8_t data_type = 0, const time_t time = 0);
|
explicit MultiDataCommand(InverterAbstract* inv, const uint64_t router_address = 0, const uint8_t data_type = 0, const time_t time = 0);
|
||||||
|
|
||||||
void setTime(const time_t time);
|
void setTime(const time_t time);
|
||||||
time_t getTime() const;
|
time_t getTime() const;
|
||||||
|
|
||||||
CommandAbstract* getRequestFrameCommand(const uint8_t frame_no);
|
CommandAbstract* getRequestFrameCommand(const uint8_t frame_no);
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setDataType(const uint8_t data_type);
|
void setDataType(const uint8_t data_type);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "ParaSetCommand.h"
|
#include "ParaSetCommand.h"
|
||||||
|
|
||||||
ParaSetCommand::ParaSetCommand(const uint64_t target_address, const uint64_t router_address)
|
ParaSetCommand::ParaSetCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: CommandAbstract(target_address, router_address)
|
: CommandAbstract(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[0] = 0x52;
|
_payload[0] = 0x52;
|
||||||
}
|
}
|
||||||
@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
class ParaSetCommand : public CommandAbstract {
|
class ParaSetCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit ParaSetCommand(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit ParaSetCommand(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -26,8 +26,8 @@ ID Target Addr Source Addr Cmd SCmd ? CRC16 CRC8
|
|||||||
|
|
||||||
#define CRC_SIZE 2
|
#define CRC_SIZE 2
|
||||||
|
|
||||||
PowerControlCommand::PowerControlCommand(const uint64_t target_address, const uint64_t router_address)
|
PowerControlCommand::PowerControlCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: DevControlCommand(target_address, router_address)
|
: DevControlCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[10] = 0x00; // TurnOn
|
_payload[10] = 0x00; // TurnOn
|
||||||
_payload[11] = 0x00;
|
_payload[11] = 0x00;
|
||||||
@ -44,20 +44,20 @@ String PowerControlCommand::getCommandName() const
|
|||||||
return "PowerControl";
|
return "PowerControl";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PowerControlCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool PowerControlCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
if (!DevControlCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!DevControlCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inverter.PowerCommand()->setLastUpdateCommand(millis());
|
_inv->PowerCommand()->setLastUpdateCommand(millis());
|
||||||
inverter.PowerCommand()->setLastPowerCommandSuccess(CMD_OK);
|
_inv->PowerCommand()->setLastPowerCommandSuccess(CMD_OK);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerControlCommand::gotTimeout(InverterAbstract& inverter)
|
void PowerControlCommand::gotTimeout()
|
||||||
{
|
{
|
||||||
inverter.PowerCommand()->setLastPowerCommandSuccess(CMD_NOK);
|
_inv->PowerCommand()->setLastPowerCommandSuccess(CMD_NOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerControlCommand::setPowerOn(const bool state)
|
void PowerControlCommand::setPowerOn(const bool state)
|
||||||
|
|||||||
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
class PowerControlCommand : public DevControlCommand {
|
class PowerControlCommand : public DevControlCommand {
|
||||||
public:
|
public:
|
||||||
explicit PowerControlCommand(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit PowerControlCommand(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
|
|
||||||
void setPowerOn(const bool state);
|
void setPowerOn(const bool state);
|
||||||
void setRestart();
|
void setRestart();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,8 +22,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
RealTimeRunDataCommand::RealTimeRunDataCommand(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
RealTimeRunDataCommand::RealTimeRunDataCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x0b);
|
setDataType(0x0b);
|
||||||
@ -35,10 +35,10 @@ String RealTimeRunDataCommand::getCommandName() const
|
|||||||
return "RealTimeRunData";
|
return "RealTimeRunData";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealTimeRunDataCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool RealTimeRunDataCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ bool RealTimeRunDataCommand::handleResponse(InverterAbstract& inverter, const fr
|
|||||||
// In case of low power in the inverter it occours that some incomplete fragments
|
// In case of low power in the inverter it occours that some incomplete fragments
|
||||||
// with a valid CRC are received.
|
// with a valid CRC are received.
|
||||||
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
||||||
const uint8_t expectedSize = inverter.Statistics()->getExpectedByteCount();
|
const uint8_t expectedSize = _inv->Statistics()->getExpectedByteCount();
|
||||||
if (fragmentsSize < expectedSize) {
|
if (fragmentsSize < expectedSize) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %d, min expected size: %d\r\n",
|
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %d, min expected size: %d\r\n",
|
||||||
getCommandName().c_str(), fragmentsSize, expectedSize);
|
getCommandName().c_str(), fragmentsSize, expectedSize);
|
||||||
@ -56,19 +56,19 @@ bool RealTimeRunDataCommand::handleResponse(InverterAbstract& inverter, const fr
|
|||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.Statistics()->beginAppendFragment();
|
_inv->Statistics()->beginAppendFragment();
|
||||||
inverter.Statistics()->clearBuffer();
|
_inv->Statistics()->clearBuffer();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
_inv->Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.Statistics()->endAppendFragment();
|
_inv->Statistics()->endAppendFragment();
|
||||||
inverter.Statistics()->resetRxFailureCount();
|
_inv->Statistics()->resetRxFailureCount();
|
||||||
inverter.Statistics()->setLastUpdate(millis());
|
_inv->Statistics()->setLastUpdate(millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealTimeRunDataCommand::gotTimeout(InverterAbstract& inverter)
|
void RealTimeRunDataCommand::gotTimeout()
|
||||||
{
|
{
|
||||||
inverter.Statistics()->incrementRxFailureCount();
|
_inv->Statistics()->incrementRxFailureCount();
|
||||||
}
|
}
|
||||||
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class RealTimeRunDataCommand : public MultiDataCommand {
|
class RealTimeRunDataCommand : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit RealTimeRunDataCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit RealTimeRunDataCommand(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,8 +22,8 @@ ID Target Addr Source Addr Frm CRC8
|
|||||||
*/
|
*/
|
||||||
#include "RequestFrameCommand.h"
|
#include "RequestFrameCommand.h"
|
||||||
|
|
||||||
RequestFrameCommand::RequestFrameCommand(const uint64_t target_address, const uint64_t router_address, uint8_t frame_no)
|
RequestFrameCommand::RequestFrameCommand(InverterAbstract* inv, const uint64_t router_address, uint8_t frame_no)
|
||||||
: SingleDataCommand(target_address, router_address)
|
: SingleDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
if (frame_no > 127) {
|
if (frame_no > 127) {
|
||||||
frame_no = 0;
|
frame_no = 0;
|
||||||
@ -47,7 +47,7 @@ uint8_t RequestFrameCommand::getFrameNo() const
|
|||||||
return _payload[9] & (~0x80);
|
return _payload[9] & (~0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestFrameCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool RequestFrameCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
class RequestFrameCommand : public SingleDataCommand {
|
class RequestFrameCommand : public SingleDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit RequestFrameCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, uint8_t frame_no = 0);
|
explicit RequestFrameCommand(InverterAbstract* inv, const uint64_t router_address = 0, uint8_t frame_no = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
void setFrameNo(const uint8_t frame_no);
|
void setFrameNo(const uint8_t frame_no);
|
||||||
uint8_t getFrameNo() const;
|
uint8_t getFrameNo() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -19,8 +19,8 @@ ID Target Addr Source Addr CRC8
|
|||||||
*/
|
*/
|
||||||
#include "SingleDataCommand.h"
|
#include "SingleDataCommand.h"
|
||||||
|
|
||||||
SingleDataCommand::SingleDataCommand(const uint64_t target_address, const uint64_t router_address)
|
SingleDataCommand::SingleDataCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: CommandAbstract(target_address, router_address)
|
: CommandAbstract(inv, router_address)
|
||||||
{
|
{
|
||||||
_payload[0] = 0x15;
|
_payload[0] = 0x15;
|
||||||
setTimeout(100);
|
setTimeout(100);
|
||||||
|
|||||||
@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
class SingleDataCommand : public CommandAbstract {
|
class SingleDataCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
explicit SingleDataCommand(const uint64_t target_address = 0, const uint64_t router_address = 0);
|
explicit SingleDataCommand(InverterAbstract* inv, const uint64_t router_address = 0);
|
||||||
};
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,8 +22,8 @@ ID Target Addr Source Addr Idx DT ? Time Gap Pa
|
|||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
#include "inverters/InverterAbstract.h"
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
SystemConfigParaCommand::SystemConfigParaCommand(const uint64_t target_address, const uint64_t router_address, const time_t time)
|
SystemConfigParaCommand::SystemConfigParaCommand(InverterAbstract* inv, const uint64_t router_address, const time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x05);
|
setDataType(0x05);
|
||||||
@ -35,10 +35,10 @@ String SystemConfigParaCommand::getCommandName() const
|
|||||||
return "SystemConfigPara";
|
return "SystemConfigPara";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SystemConfigParaCommand::handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id)
|
bool SystemConfigParaCommand::handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id)
|
||||||
{
|
{
|
||||||
// Check CRC of whole payload
|
// Check CRC of whole payload
|
||||||
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
if (!MultiDataCommand::handleResponse(fragment, max_fragment_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ bool SystemConfigParaCommand::handleResponse(InverterAbstract& inverter, const f
|
|||||||
// In case of low power in the inverter it occours that some incomplete fragments
|
// In case of low power in the inverter it occours that some incomplete fragments
|
||||||
// with a valid CRC are received.
|
// with a valid CRC are received.
|
||||||
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
const uint8_t fragmentsSize = getTotalFragmentSize(fragment, max_fragment_id);
|
||||||
const uint8_t expectedSize = inverter.SystemConfigPara()->getExpectedByteCount();
|
const uint8_t expectedSize = _inv->SystemConfigPara()->getExpectedByteCount();
|
||||||
if (fragmentsSize < expectedSize) {
|
if (fragmentsSize < expectedSize) {
|
||||||
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %d, min expected size: %d\r\n",
|
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %d, min expected size: %d\r\n",
|
||||||
getCommandName().c_str(), fragmentsSize, expectedSize);
|
getCommandName().c_str(), fragmentsSize, expectedSize);
|
||||||
@ -56,19 +56,19 @@ bool SystemConfigParaCommand::handleResponse(InverterAbstract& inverter, const f
|
|||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
inverter.SystemConfigPara()->beginAppendFragment();
|
_inv->SystemConfigPara()->beginAppendFragment();
|
||||||
inverter.SystemConfigPara()->clearBuffer();
|
_inv->SystemConfigPara()->clearBuffer();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter.SystemConfigPara()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
_inv->SystemConfigPara()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter.SystemConfigPara()->endAppendFragment();
|
_inv->SystemConfigPara()->endAppendFragment();
|
||||||
inverter.SystemConfigPara()->setLastUpdateRequest(millis());
|
_inv->SystemConfigPara()->setLastUpdateRequest(millis());
|
||||||
inverter.SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK);
|
_inv->SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemConfigParaCommand::gotTimeout(InverterAbstract& inverter)
|
void SystemConfigParaCommand::gotTimeout()
|
||||||
{
|
{
|
||||||
inverter.SystemConfigPara()->setLastLimitRequestSuccess(CMD_NOK);
|
_inv->SystemConfigPara()->setLastLimitRequestSuccess(CMD_NOK);
|
||||||
}
|
}
|
||||||
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class SystemConfigParaCommand : public MultiDataCommand {
|
class SystemConfigParaCommand : public MultiDataCommand {
|
||||||
public:
|
public:
|
||||||
explicit SystemConfigParaCommand(const uint64_t target_address = 0, const uint64_t router_address = 0, const time_t time = 0);
|
explicit SystemConfigParaCommand(InverterAbstract* inv, const uint64_t router_address = 0, const time_t time = 0);
|
||||||
|
|
||||||
virtual String getCommandName() const;
|
virtual String getCommandName() const;
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract& inverter, const fragment_t fragment[], const uint8_t max_fragment_id);
|
virtual bool handleResponse(const fragment_t fragment[], const uint8_t max_fragment_id);
|
||||||
virtual void gotTimeout(InverterAbstract& inverter);
|
virtual void gotTimeout();
|
||||||
};
|
};
|
||||||
@ -18,10 +18,9 @@ bool HMS_Abstract::sendChangeChannelRequest()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>();
|
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>(this);
|
||||||
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
|
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
|
||||||
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
|
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
|
||||||
cmdChannel->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmdChannel);
|
_radio->enqueCommand(cmdChannel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -20,10 +20,9 @@ bool HMT_Abstract::sendChangeChannelRequest()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>();
|
auto cmdChannel = _radio->prepareCommand<ChannelChangeCommand>(this);
|
||||||
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
|
cmdChannel->setCountryMode(Hoymiles.getRadioCmt()->getCountryMode());
|
||||||
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
|
cmdChannel->setChannel(Hoymiles.getRadioCmt()->getChannelFromFrequency(Hoymiles.getRadioCmt()->getInverterTargetFrequency()));
|
||||||
cmdChannel->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmdChannel);
|
_radio->enqueCommand(cmdChannel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "HM_Abstract.h"
|
#include "HM_Abstract.h"
|
||||||
#include "HoymilesRadio.h"
|
#include "HoymilesRadio.h"
|
||||||
@ -30,9 +30,8 @@ bool HM_Abstract::sendStatsRequest()
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<RealTimeRunDataCommand>();
|
auto cmd = _radio->prepareCommand<RealTimeRunDataCommand>(this);
|
||||||
cmd->setTime(now);
|
cmd->setTime(now);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -62,9 +61,8 @@ bool HM_Abstract::sendAlarmLogRequest(const bool force)
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<AlarmDataCommand>();
|
auto cmd = _radio->prepareCommand<AlarmDataCommand>(this);
|
||||||
cmd->setTime(now);
|
cmd->setTime(now);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
EventLog()->setLastAlarmRequestSuccess(CMD_PENDING);
|
EventLog()->setLastAlarmRequestSuccess(CMD_PENDING);
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
@ -85,14 +83,12 @@ bool HM_Abstract::sendDevInfoRequest()
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
auto cmdAll = _radio->prepareCommand<DevInfoAllCommand>();
|
auto cmdAll = _radio->prepareCommand<DevInfoAllCommand>(this);
|
||||||
cmdAll->setTime(now);
|
cmdAll->setTime(now);
|
||||||
cmdAll->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmdAll);
|
_radio->enqueCommand(cmdAll);
|
||||||
|
|
||||||
auto cmdSimple = _radio->prepareCommand<DevInfoSimpleCommand>();
|
auto cmdSimple = _radio->prepareCommand<DevInfoSimpleCommand>(this);
|
||||||
cmdSimple->setTime(now);
|
cmdSimple->setTime(now);
|
||||||
cmdSimple->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmdSimple);
|
_radio->enqueCommand(cmdSimple);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -112,9 +108,8 @@ bool HM_Abstract::sendSystemConfigParaRequest()
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<SystemConfigParaCommand>();
|
auto cmd = _radio->prepareCommand<SystemConfigParaCommand>(this);
|
||||||
cmd->setTime(now);
|
cmd->setTime(now);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
SystemConfigPara()->setLastLimitRequestSuccess(CMD_PENDING);
|
SystemConfigPara()->setLastLimitRequestSuccess(CMD_PENDING);
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
@ -134,9 +129,8 @@ bool HM_Abstract::sendActivePowerControlRequest(float limit, const PowerLimitCon
|
|||||||
_activePowerControlLimit = limit;
|
_activePowerControlLimit = limit;
|
||||||
_activePowerControlType = type;
|
_activePowerControlType = type;
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<ActivePowerControlCommand>();
|
auto cmd = _radio->prepareCommand<ActivePowerControlCommand>(this);
|
||||||
cmd->setActivePowerLimit(limit, type);
|
cmd->setActivePowerLimit(limit, type);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
SystemConfigPara()->setLastLimitCommandSuccess(CMD_PENDING);
|
SystemConfigPara()->setLastLimitCommandSuccess(CMD_PENDING);
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
@ -160,9 +154,8 @@ bool HM_Abstract::sendPowerControlRequest(const bool turnOn)
|
|||||||
_powerState = 0;
|
_powerState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<PowerControlCommand>();
|
auto cmd = _radio->prepareCommand<PowerControlCommand>(this);
|
||||||
cmd->setPowerOn(turnOn);
|
cmd->setPowerOn(turnOn);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
|
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
@ -177,9 +170,8 @@ bool HM_Abstract::sendRestartControlRequest()
|
|||||||
|
|
||||||
_powerState = 2;
|
_powerState = 2;
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<PowerControlCommand>();
|
auto cmd = _radio->prepareCommand<PowerControlCommand>(this);
|
||||||
cmd->setRestart();
|
cmd->setRestart();
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
|
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
@ -219,9 +211,8 @@ bool HM_Abstract::sendGridOnProFileParaRequest()
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
auto cmd = _radio->prepareCommand<GridOnProFilePara>();
|
auto cmd = _radio->prepareCommand<GridOnProFilePara>(this);
|
||||||
cmd->setTime(now);
|
cmd->setTime(now);
|
||||||
cmd->setTargetAddress(serial());
|
|
||||||
_radio->enqueCommand(cmd);
|
_radio->enqueCommand(cmd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -127,6 +127,16 @@ bool InverterAbstract::getZeroYieldDayOnMidnight() const
|
|||||||
return _zeroYieldDayOnMidnight;
|
return _zeroYieldDayOnMidnight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InverterAbstract::setClearEventlogOnMidnight(const bool enabled)
|
||||||
|
{
|
||||||
|
_clearEventlogOnMidnight = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InverterAbstract::getClearEventlogOnMidnight() const
|
||||||
|
{
|
||||||
|
return _clearEventlogOnMidnight;
|
||||||
|
}
|
||||||
|
|
||||||
bool InverterAbstract::sendChangeChannelRequest()
|
bool InverterAbstract::sendChangeChannelRequest()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -226,7 +236,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
if (cmd.getSendCount() <= cmd.getMaxResendCount()) {
|
if (cmd.getSendCount() <= cmd.getMaxResendCount()) {
|
||||||
return FRAGMENT_ALL_MISSING_RESEND;
|
return FRAGMENT_ALL_MISSING_RESEND;
|
||||||
} else {
|
} else {
|
||||||
cmd.gotTimeout(*this);
|
cmd.gotTimeout();
|
||||||
return FRAGMENT_ALL_MISSING_TIMEOUT;
|
return FRAGMENT_ALL_MISSING_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +247,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
||||||
return _rxFragmentLastPacketId + 1;
|
return _rxFragmentLastPacketId + 1;
|
||||||
} else {
|
} else {
|
||||||
cmd.gotTimeout(*this);
|
cmd.gotTimeout();
|
||||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,14 +259,14 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract& cmd)
|
|||||||
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
if (_rxFragmentRetransmitCnt++ < cmd.getMaxRetransmitCount()) {
|
||||||
return i + 1;
|
return i + 1;
|
||||||
} else {
|
} else {
|
||||||
cmd.gotTimeout(*this);
|
cmd.gotTimeout();
|
||||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd.handleResponse(*this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) {
|
if (!cmd.handleResponse(_rxFragmentBuffer, _rxFragmentMaxPacketId)) {
|
||||||
cmd.gotTimeout(*this);
|
cmd.gotTimeout();
|
||||||
return FRAGMENT_HANDLE_ERROR;
|
return FRAGMENT_HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,9 @@ public:
|
|||||||
void setZeroYieldDayOnMidnight(const bool enabled);
|
void setZeroYieldDayOnMidnight(const bool enabled);
|
||||||
bool getZeroYieldDayOnMidnight() const;
|
bool getZeroYieldDayOnMidnight() const;
|
||||||
|
|
||||||
|
void setClearEventlogOnMidnight(const bool enabled);
|
||||||
|
bool getClearEventlogOnMidnight() const;
|
||||||
|
|
||||||
void clearRxFragmentBuffer();
|
void clearRxFragmentBuffer();
|
||||||
void addRxFragment(const uint8_t fragment[], const uint8_t len);
|
void addRxFragment(const uint8_t fragment[], const uint8_t len);
|
||||||
uint8_t verifyAllFragments(CommandAbstract& cmd);
|
uint8_t verifyAllFragments(CommandAbstract& cmd);
|
||||||
@ -102,6 +105,7 @@ private:
|
|||||||
|
|
||||||
bool _zeroValuesIfUnreachable = false;
|
bool _zeroValuesIfUnreachable = false;
|
||||||
bool _zeroYieldDayOnMidnight = false;
|
bool _zeroYieldDayOnMidnight = false;
|
||||||
|
bool _clearEventlogOnMidnight = false;
|
||||||
|
|
||||||
std::unique_ptr<AlarmLogParser> _alarmLogParser;
|
std::unique_ptr<AlarmLogParser> _alarmLogParser;
|
||||||
std::unique_ptr<DevInfoParser> _devInfoParser;
|
std::unique_ptr<DevInfoParser> _devInfoParser;
|
||||||
|
|||||||
@ -1,7 +1,27 @@
|
|||||||
// 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-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This parser is used to parse the response of 'AlarmDataCommand'.
|
||||||
|
|
||||||
|
Data structure:
|
||||||
|
* wcode:
|
||||||
|
* right 8 bit: Event ID
|
||||||
|
* bit 13: Start time = PM (12h has to be added to start time)
|
||||||
|
* bit 12: End time = PM (12h has to be added to start time)
|
||||||
|
* Start: 12h based start time of the event (PM indicator in wcode)
|
||||||
|
* End: 12h based start time of the event (PM indicator in wcode)
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11
|
||||||
|
|<-------------- First log entry -------------->| |<->|
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------------
|
||||||
|
95 80 14 82 66 80 14 33 28 01 00 01 80 01 00 01 91 EA 91 EA 00 00 00 00 00 8F 65 -- -- -- -- --
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^ ^^ ^^ ^^ ^^^^^ ^^
|
||||||
|
ID Source Addr Target Addr Idx ? wcode ? Start End ? ? ? ? wcode CRC8
|
||||||
|
*/
|
||||||
#include "AlarmLogParser.h"
|
#include "AlarmLogParser.h"
|
||||||
#include "../Hoymiles.h"
|
#include "../Hoymiles.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@ -1,7 +1,32 @@
|
|||||||
// 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 - 2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This parser is used to parse the response of 'DevInfoAllCommand' and 'DevInfoSimpleCommand'.
|
||||||
|
It contains version information of the hardware and firmware. It can also be used to determine
|
||||||
|
the exact inverter type.
|
||||||
|
|
||||||
|
Data structure (DevInfoAllCommand):
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
95 80 14 82 66 80 14 33 28 81 27 1C 07 E5 04 01 07 2D 00 01 00 00 00 00 DF DD 1E -- -- -- -- --
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^
|
||||||
|
ID Source Addr Target Addr Idx FW Version FW Year FW Month/Date FW Hour/Minute Bootloader ? ? CRC16 CRC8
|
||||||
|
|
||||||
|
|
||||||
|
Data structure (DevInfoSimpleCommand):
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
95 80 14 82 66 80 14 33 28 81 27 1C 10 12 71 01 01 00 0A 00 20 01 00 00 E5 F8 95
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^
|
||||||
|
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 "../Hoymiles.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@ -2,6 +2,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 - 2024 Thomas Basler and others
|
* Copyright (C) 2023 - 2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This parser is used to parse the response of 'GridOnProFilePara'.
|
||||||
|
It contains the whole grid profile of the inverter.
|
||||||
|
|
||||||
|
Data structure:
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13
|
||||||
|
|<---------- Returns till the end of the payload ---------->|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
95 80 14 82 66 80 14 33 28 01 0A 00 20 01 00 0C 08 FC 07 A3 00 0F 09 E2 00 1E E6 -- -- -- -- --
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^
|
||||||
|
ID Source Addr Target Addr Idx Profile ID Profile Version Section ID Section Version Value Value Value Value CRC16 CRC8
|
||||||
|
|
||||||
|
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 "../Hoymiles.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -11,10 +28,10 @@
|
|||||||
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" },
|
||||||
{ 0x03, 0x01, "XX - unknown" },
|
{ 0x03, 0x01, "DE - DE_VDE4105_2011" },
|
||||||
{ 0x0a, 0x00, "XX - EN 50549-1:2019" },
|
{ 0x0a, 0x00, "XX - EN 50549-1:2019" },
|
||||||
{ 0x0c, 0x00, "AT - AT_TOR_Erzeuger_default" },
|
{ 0x0c, 0x00, "AT - AT_TOR_Erzeuger_default" },
|
||||||
{ 0x0d, 0x04, "FR -" },
|
{ 0x0d, 0x04, "XX - NF_EN_50549-1:2019" },
|
||||||
{ 0x10, 0x00, "ES - ES_RD1699" },
|
{ 0x10, 0x00, "ES - ES_RD1699" },
|
||||||
{ 0x12, 0x00, "PL - EU_EN50438" },
|
{ 0x12, 0x00, "PL - EU_EN50438" },
|
||||||
{ 0x29, 0x00, "NL - NL_NEN-EN50549-1_2019" },
|
{ 0x29, 0x00, "NL - NL_NEN-EN50549-1_2019" },
|
||||||
@ -82,7 +99,7 @@ constexpr frozen::map<uint8_t, GridProfileItemDefinition_t, 0x42> itemDefinition
|
|||||||
{ 0x1f, make_value("Start of Frequency Watt Droop (Fstart)", "Hz", 100) },
|
{ 0x1f, make_value("Start of Frequency Watt Droop (Fstart)", "Hz", 100) },
|
||||||
{ 0x20, make_value("FW Droop Slope (Kpower_Freq)", "Pn%/Hz", 10) },
|
{ 0x20, make_value("FW Droop Slope (Kpower_Freq)", "Pn%/Hz", 10) },
|
||||||
{ 0x21, make_value("Recovery Ramp Rate (RRR)", "Pn%/s", 100) },
|
{ 0x21, make_value("Recovery Ramp Rate (RRR)", "Pn%/s", 100) },
|
||||||
{ 0x22, make_value("Recovery High Frequency (RVHF)", "Hz", 100) },
|
{ 0x22, make_value("Recovery High Frequency (RVHF)", "Hz", 10) },
|
||||||
{ 0x23, make_value("Recovery Low Frequency (RVLF)", "Hz", 100) },
|
{ 0x23, make_value("Recovery Low Frequency (RVLF)", "Hz", 100) },
|
||||||
{ 0x24, make_value("VW Function Activated", "bool", 1) },
|
{ 0x24, make_value("VW Function Activated", "bool", 1) },
|
||||||
{ 0x25, make_value("Start of Voltage Watt Droop (Vstart)", "V", 10) },
|
{ 0x25, make_value("Start of Voltage Watt Droop (Vstart)", "V", 10) },
|
||||||
|
|||||||
@ -1,7 +1,21 @@
|
|||||||
// 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 - 2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This parser is used to parse the response of 'SystemConfigParaCommand'.
|
||||||
|
It contains the set inverter limit.
|
||||||
|
|
||||||
|
Data structure:
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
95 80 14 82 66 80 14 33 28 81 00 01 03 E8 00 00 03 E8 00 00 00 00 00 00 3C F8 2E -- -- -- -- --
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^
|
||||||
|
ID Source Addr Target Addr Idx ? Limit percent ? ? ? ? ? CRC16 CRC8
|
||||||
|
*/
|
||||||
#include "SystemConfigParaParser.h"
|
#include "SystemConfigParaParser.h"
|
||||||
#include "../Hoymiles.h"
|
#include "../Hoymiles.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
diff --color -ruN a/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.cpp b/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.cpp
|
|
||||||
--- a/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.cpp
|
|
||||||
+++ b/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.cpp
|
|
||||||
@@ -97,7 +97,7 @@
|
|
||||||
|
|
||||||
static inline bool _init_async_event_queue(){
|
|
||||||
if(!_async_queue){
|
|
||||||
- _async_queue = xQueueCreate(32, sizeof(lwip_event_packet_t *));
|
|
||||||
+ _async_queue = xQueueCreate(CONFIG_ASYNC_TCP_EVENT_QUEUE_SIZE, sizeof(lwip_event_packet_t *));
|
|
||||||
if(!_async_queue){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
diff --color -ruN a/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.h b/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.h
|
|
||||||
--- a/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.h
|
|
||||||
+++ b/.pio/libdeps/$$$env$$$/AsyncTCP-esphome/src/AsyncTCP.h
|
|
||||||
@@ -53,6 +53,10 @@
|
|
||||||
#define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifndef CONFIG_ASYNC_TCP_EVENT_QUEUE_SIZE
|
|
||||||
+#define CONFIG_ASYNC_TCP_EVENT_QUEUE_SIZE 32
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
class AsyncClient;
|
|
||||||
|
|
||||||
#define ASYNC_MAX_ACK_TIME 5000
|
|
||||||
@ -21,7 +21,7 @@ Import("env")
|
|||||||
platform = env.PioPlatform()
|
platform = env.PioPlatform()
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from os.path import join
|
from os.path import join, getsize
|
||||||
|
|
||||||
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
|
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
|
||||||
import esptool
|
import esptool
|
||||||
@ -60,6 +60,14 @@ def esp32_create_combined_bin(source, target, env):
|
|||||||
flash_size,
|
flash_size,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# platformio estimates the amount of flash used to store the firmware. this
|
||||||
|
# estimate is not accurate. we perform a final check on the firmware bin
|
||||||
|
# size by comparing it against the respective partition size.
|
||||||
|
max_size = env.BoardConfig().get("upload.maximum_size", 1)
|
||||||
|
fw_size = getsize(firmware_name)
|
||||||
|
if (fw_size > max_size):
|
||||||
|
raise Exception("firmware binary too large: %d > %d" % (fw_size, max_size))
|
||||||
|
|
||||||
print(" Offset | File")
|
print(" Offset | File")
|
||||||
for section in sections:
|
for section in sections:
|
||||||
sect_adr, sect_file = section.split(" ", 1)
|
sect_adr, sect_file = section.split(" ", 1)
|
||||||
|
|||||||
@ -19,7 +19,7 @@ extra_configs =
|
|||||||
custom_ci_action = generic,generic_esp32,generic_esp32s3,generic_esp32s3_usb
|
custom_ci_action = generic,generic_esp32,generic_esp32s3,generic_esp32s3_usb
|
||||||
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
platform = espressif32@6.6.0
|
platform = espressif32@6.7.0
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
-DPIOENV=\"$PIOENV\"
|
-DPIOENV=\"$PIOENV\"
|
||||||
@ -38,9 +38,9 @@ build_unflags =
|
|||||||
-std=gnu++11
|
-std=gnu++11
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
mathieucarbou/ESP Async WebServer @ 2.9.5
|
mathieucarbou/ESP Async WebServer @ 2.10.8
|
||||||
bblanchon/ArduinoJson @ 7.0.4
|
bblanchon/ArduinoJson @ 7.0.4
|
||||||
https://github.com/bertmelis/espMqttClient.git#v1.6.0
|
https://github.com/bertmelis/espMqttClient.git#v1.7.0
|
||||||
nrf24/RF24 @ 1.4.8
|
nrf24/RF24 @ 1.4.8
|
||||||
olikraus/U8g2 @ 2.35.19
|
olikraus/U8g2 @ 2.35.19
|
||||||
buelowp/sunset @ 1.1.7
|
buelowp/sunset @ 1.1.7
|
||||||
@ -61,7 +61,7 @@ board_build.embed_files =
|
|||||||
webapp_dist/js/app.js.gz
|
webapp_dist/js/app.js.gz
|
||||||
webapp_dist/site.webmanifest
|
webapp_dist/site.webmanifest
|
||||||
|
|
||||||
custom_patches = async_tcp
|
custom_patches =
|
||||||
|
|
||||||
monitor_filters = esp32_exception_decoder, time, log2file, colorize
|
monitor_filters = esp32_exception_decoder, time, log2file, colorize
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
@ -128,6 +128,7 @@ bool ConfigurationClass::write()
|
|||||||
inv["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
inv["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
||||||
inv["zero_runtime"] = config.Inverter[i].ZeroRuntimeDataIfUnrechable;
|
inv["zero_runtime"] = config.Inverter[i].ZeroRuntimeDataIfUnrechable;
|
||||||
inv["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight;
|
inv["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight;
|
||||||
|
inv["clear_eventlog"] = config.Inverter[i].ClearEventlogOnMidnight;
|
||||||
inv["yieldday_correction"] = config.Inverter[i].YieldDayCorrection;
|
inv["yieldday_correction"] = config.Inverter[i].YieldDayCorrection;
|
||||||
|
|
||||||
JsonArray channel = inv["channel"].to<JsonArray>();
|
JsonArray channel = inv["channel"].to<JsonArray>();
|
||||||
@ -302,6 +303,7 @@ bool ConfigurationClass::read()
|
|||||||
config.Inverter[i].ReachableThreshold = inv["reachable_threshold"] | REACHABLE_THRESHOLD;
|
config.Inverter[i].ReachableThreshold = inv["reachable_threshold"] | REACHABLE_THRESHOLD;
|
||||||
config.Inverter[i].ZeroRuntimeDataIfUnrechable = inv["zero_runtime"] | false;
|
config.Inverter[i].ZeroRuntimeDataIfUnrechable = inv["zero_runtime"] | false;
|
||||||
config.Inverter[i].ZeroYieldDayOnMidnight = inv["zero_day"] | false;
|
config.Inverter[i].ZeroYieldDayOnMidnight = inv["zero_day"] | false;
|
||||||
|
config.Inverter[i].ClearEventlogOnMidnight = inv["clear_eventlog"] | false;
|
||||||
config.Inverter[i].YieldDayCorrection = inv["yieldday_correction"] | false;
|
config.Inverter[i].YieldDayCorrection = inv["yieldday_correction"] | false;
|
||||||
|
|
||||||
JsonArray channel = inv["channel"];
|
JsonArray channel = inv["channel"];
|
||||||
|
|||||||
@ -82,6 +82,7 @@ void InverterSettingsClass::init(Scheduler& scheduler)
|
|||||||
inv->setReachableThreshold(config.Inverter[i].ReachableThreshold);
|
inv->setReachableThreshold(config.Inverter[i].ReachableThreshold);
|
||||||
inv->setZeroValuesIfUnreachable(config.Inverter[i].ZeroRuntimeDataIfUnrechable);
|
inv->setZeroValuesIfUnreachable(config.Inverter[i].ZeroRuntimeDataIfUnrechable);
|
||||||
inv->setZeroYieldDayOnMidnight(config.Inverter[i].ZeroYieldDayOnMidnight);
|
inv->setZeroYieldDayOnMidnight(config.Inverter[i].ZeroYieldDayOnMidnight);
|
||||||
|
inv->setClearEventlogOnMidnight(config.Inverter[i].ClearEventlogOnMidnight);
|
||||||
inv->Statistics()->setYieldDayCorrection(config.Inverter[i].YieldDayCorrection);
|
inv->Statistics()->setYieldDayCorrection(config.Inverter[i].YieldDayCorrection);
|
||||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||||
inv->Statistics()->setStringMaxPower(c, config.Inverter[i].channel[c].MaxChannelPower);
|
inv->Statistics()->setStringMaxPower(c, config.Inverter[i].channel[c].MaxChannelPower);
|
||||||
|
|||||||
@ -25,20 +25,7 @@ MqttHandleInverterClass::MqttHandleInverterClass()
|
|||||||
|
|
||||||
void MqttHandleInverterClass::init(Scheduler& scheduler)
|
void MqttHandleInverterClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
subscribeTopics();
|
||||||
using std::placeholders::_2;
|
|
||||||
using std::placeholders::_3;
|
|
||||||
using std::placeholders::_4;
|
|
||||||
using std::placeholders::_5;
|
|
||||||
using std::placeholders::_6;
|
|
||||||
|
|
||||||
const String topic = MqttSettings.getPrefix();
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_RELATIVE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_ABSOLUTE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_RELATIVE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_ABSOLUTE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_POWER), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_RESTART), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
|
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
||||||
@ -247,3 +234,32 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MqttHandleInverterClass::subscribeTopics()
|
||||||
|
{
|
||||||
|
using std::placeholders::_1;
|
||||||
|
using std::placeholders::_2;
|
||||||
|
using std::placeholders::_3;
|
||||||
|
using std::placeholders::_4;
|
||||||
|
using std::placeholders::_5;
|
||||||
|
using std::placeholders::_6;
|
||||||
|
|
||||||
|
const String topic = MqttSettings.getPrefix();
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_RELATIVE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_ABSOLUTE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_RELATIVE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_ABSOLUTE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_POWER), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_RESTART), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MqttHandleInverterClass::unsubscribeTopics()
|
||||||
|
{
|
||||||
|
const String topic = MqttSettings.getPrefix();
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_RELATIVE));
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_ABSOLUTE));
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_RELATIVE));
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_ABSOLUTE));
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_POWER));
|
||||||
|
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_RESTART));
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +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 - 2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Display_Graphic.h"
|
#include "Display_Graphic.h"
|
||||||
#include "Led_Single.h"
|
#include "Led_Single.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include "PinMapping.h"
|
|
||||||
#include <Esp.h>
|
#include <Esp.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,7 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
|
|||||||
obj["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
obj["reachable_threshold"] = config.Inverter[i].ReachableThreshold;
|
||||||
obj["zero_runtime"] = config.Inverter[i].ZeroRuntimeDataIfUnrechable;
|
obj["zero_runtime"] = config.Inverter[i].ZeroRuntimeDataIfUnrechable;
|
||||||
obj["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight;
|
obj["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight;
|
||||||
|
obj["clear_eventlog"] = config.Inverter[i].ClearEventlogOnMidnight;
|
||||||
obj["yieldday_correction"] = config.Inverter[i].YieldDayCorrection;
|
obj["yieldday_correction"] = config.Inverter[i].YieldDayCorrection;
|
||||||
|
|
||||||
auto inv = Hoymiles.getInverterBySerial(config.Inverter[i].Serial);
|
auto inv = Hoymiles.getInverterBySerial(config.Inverter[i].Serial);
|
||||||
@ -213,20 +214,21 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
|||||||
inverter.Serial = new_serial;
|
inverter.Serial = new_serial;
|
||||||
strncpy(inverter.Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
strncpy(inverter.Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
||||||
|
|
||||||
|
inverter.Poll_Enable = root["poll_enable"] | true;
|
||||||
|
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;
|
||||||
|
inverter.ZeroRuntimeDataIfUnrechable = root["zero_runtime"] | false;
|
||||||
|
inverter.ZeroYieldDayOnMidnight = root["zero_day"] | false;
|
||||||
|
inverter.ClearEventlogOnMidnight = root["clear_eventlog"] | false;
|
||||||
|
inverter.YieldDayCorrection = root["yieldday_correction"] | false;
|
||||||
|
|
||||||
uint8_t arrayCount = 0;
|
uint8_t arrayCount = 0;
|
||||||
for (JsonVariant channel : channelArray) {
|
for (JsonVariant channel : channelArray) {
|
||||||
inverter.channel[arrayCount].MaxChannelPower = channel["max_power"].as<uint16_t>();
|
inverter.channel[arrayCount].MaxChannelPower = channel["max_power"].as<uint16_t>();
|
||||||
inverter.channel[arrayCount].YieldTotalOffset = channel["yield_total_offset"].as<float>();
|
inverter.channel[arrayCount].YieldTotalOffset = channel["yield_total_offset"].as<float>();
|
||||||
strncpy(inverter.channel[arrayCount].Name, channel["name"] | "", sizeof(inverter.channel[arrayCount].Name));
|
strncpy(inverter.channel[arrayCount].Name, channel["name"] | "", sizeof(inverter.channel[arrayCount].Name));
|
||||||
inverter.Poll_Enable = root["poll_enable"] | true;
|
|
||||||
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;
|
|
||||||
inverter.ZeroRuntimeDataIfUnrechable = root["zero_runtime"] | false;
|
|
||||||
inverter.ZeroYieldDayOnMidnight = root["zero_day"] | false;
|
|
||||||
inverter.YieldDayCorrection = root["yieldday_correction"] | false;
|
|
||||||
|
|
||||||
arrayCount++;
|
arrayCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +256,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
|||||||
inv->setReachableThreshold(inverter.ReachableThreshold);
|
inv->setReachableThreshold(inverter.ReachableThreshold);
|
||||||
inv->setZeroValuesIfUnreachable(inverter.ZeroRuntimeDataIfUnrechable);
|
inv->setZeroValuesIfUnreachable(inverter.ZeroRuntimeDataIfUnrechable);
|
||||||
inv->setZeroYieldDayOnMidnight(inverter.ZeroYieldDayOnMidnight);
|
inv->setZeroYieldDayOnMidnight(inverter.ZeroYieldDayOnMidnight);
|
||||||
|
inv->setClearEventlogOnMidnight(inverter.ClearEventlogOnMidnight);
|
||||||
inv->Statistics()->setYieldDayCorrection(inverter.YieldDayCorrection);
|
inv->Statistics()->setYieldDayCorrection(inverter.YieldDayCorrection);
|
||||||
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
|
||||||
inv->Statistics()->setStringMaxPower(c, inverter.channel[c].MaxChannelPower);
|
inv->Statistics()->setStringMaxPower(c, inverter.channel[c].MaxChannelPower);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "WebApi_mqtt.h"
|
#include "WebApi_mqtt.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MqttHandleHass.h"
|
#include "MqttHandleHass.h"
|
||||||
|
#include "MqttHandleInverter.h"
|
||||||
#include "MqttSettings.h"
|
#include "MqttSettings.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
@ -76,7 +77,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
|
|||||||
root["mqtt_client_cert"] = config.Mqtt.Tls.ClientCert;
|
root["mqtt_client_cert"] = config.Mqtt.Tls.ClientCert;
|
||||||
root["mqtt_client_key"] = config.Mqtt.Tls.ClientKey;
|
root["mqtt_client_key"] = config.Mqtt.Tls.ClientKey;
|
||||||
root["mqtt_lwt_topic"] = config.Mqtt.Lwt.Topic;
|
root["mqtt_lwt_topic"] = config.Mqtt.Lwt.Topic;
|
||||||
root["mqtt_lwt_online"] = config.Mqtt.Lwt.Value_Online;;
|
root["mqtt_lwt_online"] = config.Mqtt.Lwt.Value_Online;
|
||||||
root["mqtt_lwt_offline"] = config.Mqtt.Lwt.Value_Offline;
|
root["mqtt_lwt_offline"] = config.Mqtt.Lwt.Value_Offline;
|
||||||
root["mqtt_lwt_qos"] = config.Mqtt.Lwt.Qos;
|
root["mqtt_lwt_qos"] = config.Mqtt.Lwt.Qos;
|
||||||
root["mqtt_publish_interval"] = config.Mqtt.PublishInterval;
|
root["mqtt_publish_interval"] = config.Mqtt.PublishInterval;
|
||||||
@ -272,7 +273,6 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
strlcpy(config.Mqtt.Hostname, root["mqtt_hostname"].as<String>().c_str(), sizeof(config.Mqtt.Hostname));
|
strlcpy(config.Mqtt.Hostname, root["mqtt_hostname"].as<String>().c_str(), sizeof(config.Mqtt.Hostname));
|
||||||
strlcpy(config.Mqtt.Username, root["mqtt_username"].as<String>().c_str(), sizeof(config.Mqtt.Username));
|
strlcpy(config.Mqtt.Username, root["mqtt_username"].as<String>().c_str(), sizeof(config.Mqtt.Username));
|
||||||
strlcpy(config.Mqtt.Password, root["mqtt_password"].as<String>().c_str(), sizeof(config.Mqtt.Password));
|
strlcpy(config.Mqtt.Password, root["mqtt_password"].as<String>().c_str(), sizeof(config.Mqtt.Password));
|
||||||
strlcpy(config.Mqtt.Topic, root["mqtt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Topic));
|
|
||||||
strlcpy(config.Mqtt.Lwt.Topic, root["mqtt_lwt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Topic));
|
strlcpy(config.Mqtt.Lwt.Topic, root["mqtt_lwt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Topic));
|
||||||
strlcpy(config.Mqtt.Lwt.Value_Online, root["mqtt_lwt_online"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Value_Online));
|
strlcpy(config.Mqtt.Lwt.Value_Online, root["mqtt_lwt_online"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Value_Online));
|
||||||
strlcpy(config.Mqtt.Lwt.Value_Offline, root["mqtt_lwt_offline"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Value_Offline));
|
strlcpy(config.Mqtt.Lwt.Value_Offline, root["mqtt_lwt_offline"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Value_Offline));
|
||||||
@ -285,6 +285,13 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
config.Mqtt.Hass.IndividualPanels = root["mqtt_hass_individualpanels"].as<bool>();
|
config.Mqtt.Hass.IndividualPanels = root["mqtt_hass_individualpanels"].as<bool>();
|
||||||
strlcpy(config.Mqtt.Hass.Topic, root["mqtt_hass_topic"].as<String>().c_str(), sizeof(config.Mqtt.Hass.Topic));
|
strlcpy(config.Mqtt.Hass.Topic, root["mqtt_hass_topic"].as<String>().c_str(), sizeof(config.Mqtt.Hass.Topic));
|
||||||
|
|
||||||
|
// Check if base topic was changed
|
||||||
|
if (strcmp(config.Mqtt.Topic, root["mqtt_topic"].as<String>().c_str())) {
|
||||||
|
MqttHandleInverter.unsubscribeTopics();
|
||||||
|
strlcpy(config.Mqtt.Topic, root["mqtt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Topic));
|
||||||
|
MqttHandleInverter.subscribeTopics();
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||||
|
|||||||
@ -7,11 +7,12 @@
|
|||||||
#include "NetworkSettings.h"
|
#include "NetworkSettings.h"
|
||||||
#include "PinMapping.h"
|
#include "PinMapping.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
|
#include "__compiled_constants.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
#include <CpuTemperature.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <ResetReason.h>
|
#include <ResetReason.h>
|
||||||
#include "__compiled_constants.h"
|
|
||||||
|
|
||||||
void WebApiSysstatusClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
void WebApiSysstatusClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
@ -33,6 +34,7 @@ void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
root["sdkversion"] = ESP.getSdkVersion();
|
root["sdkversion"] = ESP.getSdkVersion();
|
||||||
root["cpufreq"] = ESP.getCpuFreqMHz();
|
root["cpufreq"] = ESP.getCpuFreqMHz();
|
||||||
|
root["cputemp"] = CpuTemperature.read();
|
||||||
|
|
||||||
root["heap_total"] = ESP.getHeapSize();
|
root["heap_total"] = ESP.getHeapSize();
|
||||||
root["heap_used"] = ESP.getHeapSize() - ESP.getFreeHeap();
|
root["heap_used"] = ESP.getHeapSize() - ESP.getFreeHeap();
|
||||||
@ -48,6 +50,7 @@ void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
|||||||
root["chiprevision"] = ESP.getChipRevision();
|
root["chiprevision"] = ESP.getChipRevision();
|
||||||
root["chipmodel"] = ESP.getChipModel();
|
root["chipmodel"] = ESP.getChipModel();
|
||||||
root["chipcores"] = ESP.getChipCores();
|
root["chipcores"] = ESP.getChipCores();
|
||||||
|
root["flashsize"] = ESP.getFlashChipSize();
|
||||||
|
|
||||||
String reason;
|
String reason;
|
||||||
reason = ResetReason::get_reset_reason_verbose(0);
|
reason = ResetReason::get_reset_reason_verbose(0);
|
||||||
|
|||||||
@ -18,31 +18,31 @@
|
|||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"sortablejs": "^1.15.2",
|
"sortablejs": "^1.15.2",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"vue": "^3.4.26",
|
"vue": "^3.4.27",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue-i18n": "^9.13.1",
|
||||||
"vue-router": "^4.3.2"
|
"vue-router": "^4.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||||
"@tsconfig/node18": "^18.2.4",
|
"@tsconfig/node18": "^18.2.4",
|
||||||
"@types/bootstrap": "^5.2.10",
|
"@types/bootstrap": "^5.2.10",
|
||||||
"@types/node": "^20.12.10",
|
"@types/node": "^20.14.2",
|
||||||
"@types/pulltorefreshjs": "^0.1.7",
|
"@types/pulltorefreshjs": "^0.1.7",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@types/spark-md5": "^3.0.4",
|
"@types/spark-md5": "^3.0.4",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"@vue/eslint-config-typescript": "^13.0.0",
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"eslint": "^9.2.0",
|
"eslint": "^9.4.0",
|
||||||
"eslint-plugin-vue": "^9.25.0",
|
"eslint-plugin-vue": "^9.26.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"pulltorefreshjs": "^0.1.22",
|
"pulltorefreshjs": "^0.1.22",
|
||||||
"sass": "^1.76.0",
|
"sass": "^1.77.4",
|
||||||
"terser": "^5.31.0",
|
"terser": "^5.31.1",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"vite": "^5.2.11",
|
"vite": "^5.2.13",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-css-injected-by-js": "^3.5.1",
|
"vite-plugin-css-injected-by-js": "^3.5.1",
|
||||||
"vue-tsc": "^2.0.16"
|
"vue-tsc": "^2.0.21"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,17 @@
|
|||||||
<th>{{ $t('hardwareinfo.CpuFrequency') }}</th>
|
<th>{{ $t('hardwareinfo.CpuFrequency') }}</th>
|
||||||
<td>{{ systemStatus.cpufreq }} {{ $t('hardwareinfo.Mhz') }}</td>
|
<td>{{ systemStatus.cpufreq }} {{ $t('hardwareinfo.Mhz') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('hardwareinfo.CpuTemperature') }}</th>
|
||||||
|
<td>{{ $n(systemStatus.cputemp, 'celsius') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('hardwareinfo.FlashSize') }}</th>
|
||||||
|
<td>
|
||||||
|
{{ $n(systemStatus.flashsize, 'byte') }}
|
||||||
|
({{ $n(systemStatus.flashsize / 1024 / 1024, 'megabyte') }})
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -65,8 +65,8 @@
|
|||||||
"4009": "Wechselrichter Reihenfolge gespeichert!",
|
"4009": "Wechselrichter Reihenfolge gespeichert!",
|
||||||
"5001": "@:apiresponse.2001",
|
"5001": "@:apiresponse.2001",
|
||||||
"5002": "Das Limit muss zwischen 1 und {max} sein!",
|
"5002": "Das Limit muss zwischen 1 und {max} sein!",
|
||||||
"5003": "Ungültiten Typ angegeben!",
|
"5003": "Ungültiger Typ angegeben!",
|
||||||
"5004": "Ungültigen Inverter angegeben!",
|
"5004": "Ungültiger Inverter angegeben!",
|
||||||
"6001": "Neustart durchgeführt!",
|
"6001": "Neustart durchgeführt!",
|
||||||
"6002": "Neustart abgebrochen!",
|
"6002": "Neustart abgebrochen!",
|
||||||
"7001": "MQTT-Server muss zwischen 1 und {max} Zeichen lang sein!",
|
"7001": "MQTT-Server muss zwischen 1 und {max} Zeichen lang sein!",
|
||||||
@ -143,7 +143,7 @@
|
|||||||
"LoadingInverter": "Warte auf Daten... (kann bis zu 10 Sekunden dauern)"
|
"LoadingInverter": "Warte auf Daten... (kann bis zu 10 Sekunden dauern)"
|
||||||
},
|
},
|
||||||
"eventlog": {
|
"eventlog": {
|
||||||
"Start": "Begin",
|
"Start": "Beginn",
|
||||||
"Stop": "Ende",
|
"Stop": "Ende",
|
||||||
"Id": "ID",
|
"Id": "ID",
|
||||||
"Message": "Meldung"
|
"Message": "Meldung"
|
||||||
@ -202,7 +202,9 @@
|
|||||||
"ChipRevision": "Chip-Revision",
|
"ChipRevision": "Chip-Revision",
|
||||||
"ChipCores": "Chip-Kerne",
|
"ChipCores": "Chip-Kerne",
|
||||||
"CpuFrequency": "CPU-Frequenz",
|
"CpuFrequency": "CPU-Frequenz",
|
||||||
"Mhz": "MHz"
|
"Mhz": "MHz",
|
||||||
|
"CpuTemperature": "CPU-Temperatur",
|
||||||
|
"FlashSize": "Flash-Speichergröße"
|
||||||
},
|
},
|
||||||
"memoryinfo": {
|
"memoryinfo": {
|
||||||
"MemoryInformation": "Speicherinformationen",
|
"MemoryInformation": "Speicherinformationen",
|
||||||
@ -513,6 +515,7 @@
|
|||||||
"ZeroRuntimeHint": "Nulle Laufzeit Daten (keine Ertragsdaten), wenn der Wechselrichter nicht erreichbar ist.",
|
"ZeroRuntimeHint": "Nulle Laufzeit Daten (keine Ertragsdaten), wenn der Wechselrichter nicht erreichbar ist.",
|
||||||
"ZeroDay": "Nulle Tagesertrag um Mitternacht",
|
"ZeroDay": "Nulle Tagesertrag um Mitternacht",
|
||||||
"ZeroDayHint": "Das funktioniert nur wenn der Wechselrichter nicht erreichbar ist. Wenn Daten aus dem Wechselrichter gelesen werden, werden deren Werte verwendet. (Ein Reset erfolgt nur beim Neustarten)",
|
"ZeroDayHint": "Das funktioniert nur wenn der Wechselrichter nicht erreichbar ist. Wenn Daten aus dem Wechselrichter gelesen werden, werden deren Werte verwendet. (Ein Reset erfolgt nur beim Neustarten)",
|
||||||
|
"ClearEventlog": "Lösche Ereignisanzeige um Mitternacht",
|
||||||
"Cancel": "@:base.Cancel",
|
"Cancel": "@:base.Cancel",
|
||||||
"Save": "@:base.Save",
|
"Save": "@:base.Save",
|
||||||
"DeleteMsg": "Soll der Wechselrichter \"{name}\" mit der Seriennummer {serial} wirklich gelöscht werden?",
|
"DeleteMsg": "Soll der Wechselrichter \"{name}\" mit der Seriennummer {serial} wirklich gelöscht werden?",
|
||||||
@ -590,9 +593,9 @@
|
|||||||
"DefaultProfile": "(Standardeinstellungen)",
|
"DefaultProfile": "(Standardeinstellungen)",
|
||||||
"ProfileHint": "Ihr Gerät reagiert möglicherweise nicht mehr, wenn Sie ein inkompatibles Profil wählen. In diesem Fall müssen Sie eine Löschung über das serielle Interface durchführen.",
|
"ProfileHint": "Ihr Gerät reagiert möglicherweise nicht mehr, wenn Sie ein inkompatibles Profil wählen. In diesem Fall müssen Sie eine Löschung über das serielle Interface durchführen.",
|
||||||
"Display": "Display",
|
"Display": "Display",
|
||||||
"PowerSafe": "Stromsparen aktivieren:",
|
"PowerSafe": "Ausschalten wenn kein Inverter erreichbar:",
|
||||||
"PowerSafeHint": "Schaltet das Display aus, wenn kein Wechselrichter Strom erzeugt",
|
"PowerSafeHint": "Schaltet das Display aus, wenn kein Wechselrichter Strom erzeugt",
|
||||||
"Screensaver": "Bildschirmschoner aktivieren:",
|
"Screensaver": "OLED-Schutz gegen Einbrennen:",
|
||||||
"ScreensaverHint": "Bewegt die Ausgabe bei jeder Aktualisierung um ein Einbrennen zu verhindern (v. a. für OLED-Displays nützlich)",
|
"ScreensaverHint": "Bewegt die Ausgabe bei jeder Aktualisierung um ein Einbrennen zu verhindern (v. a. für OLED-Displays nützlich)",
|
||||||
"DiagramMode": "Diagramm Modus:",
|
"DiagramMode": "Diagramm Modus:",
|
||||||
"off": "Deaktiviert",
|
"off": "Deaktiviert",
|
||||||
|
|||||||
@ -202,7 +202,9 @@
|
|||||||
"ChipRevision": "Chip Revision",
|
"ChipRevision": "Chip Revision",
|
||||||
"ChipCores": "Chip Cores",
|
"ChipCores": "Chip Cores",
|
||||||
"CpuFrequency": "CPU Frequency",
|
"CpuFrequency": "CPU Frequency",
|
||||||
"Mhz": "MHz"
|
"Mhz": "MHz",
|
||||||
|
"CpuTemperature": "CPU Temperature",
|
||||||
|
"FlashSize": "Flash Memory Size"
|
||||||
},
|
},
|
||||||
"memoryinfo": {
|
"memoryinfo": {
|
||||||
"MemoryInformation": "Memory Information",
|
"MemoryInformation": "Memory Information",
|
||||||
@ -513,6 +515,7 @@
|
|||||||
"ZeroRuntimeHint": "Zero runtime data (no yield data) if inverter becomes unreachable.",
|
"ZeroRuntimeHint": "Zero runtime data (no yield data) if inverter becomes unreachable.",
|
||||||
"ZeroDay": "Zero daily yield at midnight",
|
"ZeroDay": "Zero daily yield at midnight",
|
||||||
"ZeroDayHint": "This only works if the inverter is unreachable. If data is read from the inverter, it's values will be used. (Reset only occours on power cycle)",
|
"ZeroDayHint": "This only works if the inverter is unreachable. If data is read from the inverter, it's values will be used. (Reset only occours on power cycle)",
|
||||||
|
"ClearEventlog": "Clear Eventlog at midnight",
|
||||||
"Cancel": "@:base.Cancel",
|
"Cancel": "@:base.Cancel",
|
||||||
"Save": "@:base.Save",
|
"Save": "@:base.Save",
|
||||||
"DeleteMsg": "Are you sure you want to delete the inverter \"{name}\" with serial number {serial}?",
|
"DeleteMsg": "Are you sure you want to delete the inverter \"{name}\" with serial number {serial}?",
|
||||||
@ -590,9 +593,9 @@
|
|||||||
"DefaultProfile": "(Default settings)",
|
"DefaultProfile": "(Default settings)",
|
||||||
"ProfileHint": "Your device may stop responding if you select an incompatible profile. In this case, you must perform a deletion via the serial interface.",
|
"ProfileHint": "Your device may stop responding if you select an incompatible profile. In this case, you must perform a deletion via the serial interface.",
|
||||||
"Display": "Display",
|
"Display": "Display",
|
||||||
"PowerSafe": "Enable Power Save:",
|
"PowerSafe": "Switch off if no solar:",
|
||||||
"PowerSafeHint": "Turn off the display if no inverter is producing.",
|
"PowerSafeHint": "Turn off the display if no inverter is producing.",
|
||||||
"Screensaver": "Enable Screensaver:",
|
"Screensaver": "OLED Anti burn-in:",
|
||||||
"ScreensaverHint": "Move the display a little bit on each update to prevent burn-in. (Useful especially for OLED displays)",
|
"ScreensaverHint": "Move the display a little bit on each update to prevent burn-in. (Useful especially for OLED displays)",
|
||||||
"DiagramMode": "Diagram mode:",
|
"DiagramMode": "Diagram mode:",
|
||||||
"off": "Off",
|
"off": "Off",
|
||||||
|
|||||||
@ -202,7 +202,9 @@
|
|||||||
"ChipRevision": "Révision de la puce",
|
"ChipRevision": "Révision de la puce",
|
||||||
"ChipCores": "Nombre de cœurs",
|
"ChipCores": "Nombre de cœurs",
|
||||||
"CpuFrequency": "Fréquence du CPU",
|
"CpuFrequency": "Fréquence du CPU",
|
||||||
"Mhz": "MHz"
|
"Mhz": "MHz",
|
||||||
|
"CpuTemperature": "CPU Temperature",
|
||||||
|
"FlashSize": "Taille de la mémoire flash"
|
||||||
},
|
},
|
||||||
"memoryinfo": {
|
"memoryinfo": {
|
||||||
"MemoryInformation": "Informations sur la mémoire",
|
"MemoryInformation": "Informations sur la mémoire",
|
||||||
@ -513,6 +515,7 @@
|
|||||||
"ZeroRuntimeHint": "Zero runtime data (no yield data) if inverter becomes unreachable.",
|
"ZeroRuntimeHint": "Zero runtime data (no yield data) if inverter becomes unreachable.",
|
||||||
"ZeroDay": "Zero daily yield at midnight",
|
"ZeroDay": "Zero daily yield at midnight",
|
||||||
"ZeroDayHint": "This only works if the inverter is unreachable. If data is read from the inverter, it's values will be used. (Reset only occours on power cycle)",
|
"ZeroDayHint": "This only works if the inverter is unreachable. If data is read from the inverter, it's values will be used. (Reset only occours on power cycle)",
|
||||||
|
"ClearEventlog": "Clear Eventlog at midnight",
|
||||||
"Cancel": "@:base.Cancel",
|
"Cancel": "@:base.Cancel",
|
||||||
"Save": "@:base.Save",
|
"Save": "@:base.Save",
|
||||||
"DeleteMsg": "Êtes-vous sûr de vouloir supprimer l'onduleur \"{name}\" avec le numéro de série \"{serial}\" ?",
|
"DeleteMsg": "Êtes-vous sûr de vouloir supprimer l'onduleur \"{name}\" avec le numéro de série \"{serial}\" ?",
|
||||||
@ -590,9 +593,9 @@
|
|||||||
"DefaultProfile": "(Réglages par défaut)",
|
"DefaultProfile": "(Réglages par défaut)",
|
||||||
"ProfileHint": "Votre appareil peut cesser de répondre si vous sélectionnez un profil incompatible. Dans ce cas, vous devez effectuer une suppression via l'interface série.",
|
"ProfileHint": "Votre appareil peut cesser de répondre si vous sélectionnez un profil incompatible. Dans ce cas, vous devez effectuer une suppression via l'interface série.",
|
||||||
"Display": "Affichage",
|
"Display": "Affichage",
|
||||||
"PowerSafe": "Activer l'économiseur d'énergie",
|
"PowerSafe": "Economiseur d'énergie",
|
||||||
"PowerSafeHint": "Eteindre l'écran si aucun onduleur n'est en production.",
|
"PowerSafeHint": "Eteindre l'écran si aucun onduleur n'est en production.",
|
||||||
"Screensaver": "Activer l'écran de veille",
|
"Screensaver": "OLED Anti burn-in",
|
||||||
"ScreensaverHint": "Déplacez un peu l'écran à chaque mise à jour pour éviter le phénomène de brûlure. (Utile surtout pour les écrans OLED)",
|
"ScreensaverHint": "Déplacez un peu l'écran à chaque mise à jour pour éviter le phénomène de brûlure. (Utile surtout pour les écrans OLED)",
|
||||||
"DiagramMode": "Diagram mode:",
|
"DiagramMode": "Diagram mode:",
|
||||||
"off": "Off",
|
"off": "Off",
|
||||||
|
|||||||
@ -12,44 +12,23 @@ export const LOCALES = [
|
|||||||
{ value: Locales.FR, caption: 'Français' },
|
{ value: Locales.FR, caption: 'Français' },
|
||||||
]
|
]
|
||||||
|
|
||||||
export const dateTimeFormats: I18nOptions["datetimeFormats"] = {
|
export const dateTimeFormats: I18nOptions["datetimeFormats"] = {};
|
||||||
[Locales.EN]: {
|
export const numberFormats: I18nOptions["numberFormats"] = {};
|
||||||
'datetime': {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
second: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'numeric',
|
|
||||||
day: 'numeric',
|
|
||||||
hour12: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[Locales.DE]: {
|
|
||||||
'datetime': {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
second: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'numeric',
|
|
||||||
day: 'numeric',
|
|
||||||
hour12: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[Locales.FR]: {
|
|
||||||
'datetime': {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
second: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'numeric',
|
|
||||||
day: 'numeric',
|
|
||||||
hour12: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const numberFormats: I18nOptions["numberFormats"] = {
|
LOCALES.forEach((locale) => {
|
||||||
[Locales.EN]: {
|
dateTimeFormats[locale.value] = {
|
||||||
|
'datetime': {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
second: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'numeric',
|
||||||
|
day: 'numeric',
|
||||||
|
hour12: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
numberFormats[locale.value] = {
|
||||||
decimal: {
|
decimal: {
|
||||||
style: 'decimal',
|
style: 'decimal',
|
||||||
},
|
},
|
||||||
@ -62,44 +41,19 @@ export const numberFormats: I18nOptions["numberFormats"] = {
|
|||||||
percent: {
|
percent: {
|
||||||
style: 'percent',
|
style: 'percent',
|
||||||
},
|
},
|
||||||
kilobyte: {
|
byte: {
|
||||||
style: 'unit', unit: 'kilobyte',
|
style: 'unit', unit: 'byte',
|
||||||
},
|
|
||||||
},
|
|
||||||
[Locales.DE]: {
|
|
||||||
decimal: {
|
|
||||||
style: 'decimal',
|
|
||||||
},
|
|
||||||
decimalNoDigits: {
|
|
||||||
style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0
|
|
||||||
},
|
|
||||||
decimalTwoDigits: {
|
|
||||||
style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2
|
|
||||||
},
|
|
||||||
percent: {
|
|
||||||
style: 'percent',
|
|
||||||
},
|
},
|
||||||
kilobyte: {
|
kilobyte: {
|
||||||
style: 'unit', unit: 'kilobyte',
|
style: 'unit', unit: 'kilobyte',
|
||||||
},
|
},
|
||||||
},
|
megabyte: {
|
||||||
[Locales.FR]: {
|
style: 'unit', unit: 'megabyte',
|
||||||
decimal: {
|
|
||||||
style: 'decimal',
|
|
||||||
},
|
},
|
||||||
decimalNoDigits: {
|
celsius: {
|
||||||
style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0
|
style: 'unit', unit: 'celsius', maximumFractionDigits: 1,
|
||||||
},
|
},
|
||||||
decimalTwoDigits: {
|
};
|
||||||
style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2
|
});
|
||||||
},
|
|
||||||
percent: {
|
|
||||||
style: 'percent',
|
|
||||||
},
|
|
||||||
kilobyte: {
|
|
||||||
style: 'unit', unit: 'kilobyte',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defaultLocale = Locales.EN;
|
export const defaultLocale = Locales.EN;
|
||||||
@ -17,6 +17,7 @@ export interface Inverter {
|
|||||||
reachable_threshold: number;
|
reachable_threshold: number;
|
||||||
zero_runtime: boolean;
|
zero_runtime: boolean;
|
||||||
zero_day: boolean;
|
zero_day: boolean;
|
||||||
|
clear_eventlog: boolean;
|
||||||
yieldday_correction: boolean;
|
yieldday_correction: boolean;
|
||||||
channel: Array<InverterChannel>;
|
channel: Array<InverterChannel>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ export interface SystemStatus {
|
|||||||
chiprevision: number;
|
chiprevision: number;
|
||||||
chipcores: number;
|
chipcores: number;
|
||||||
cpufreq: number;
|
cpufreq: number;
|
||||||
|
cputemp: number;
|
||||||
|
flashsize: number;
|
||||||
// FirmwareInfo
|
// FirmwareInfo
|
||||||
hostname: string;
|
hostname: string;
|
||||||
sdkversion: string;
|
sdkversion: string;
|
||||||
|
|||||||
@ -176,6 +176,8 @@
|
|||||||
<InputElement :label="$t('inverteradmin.ZeroDay')" v-model="selectedInverterData.zero_day" type="checkbox"
|
<InputElement :label="$t('inverteradmin.ZeroDay')" v-model="selectedInverterData.zero_day" type="checkbox"
|
||||||
:tooltip="$t('inverteradmin.ZeroDayHint')" wide />
|
:tooltip="$t('inverteradmin.ZeroDayHint')" wide />
|
||||||
|
|
||||||
|
<InputElement :label="$t('inverteradmin.ClearEventlog')" v-model="selectedInverterData.clear_eventlog" type="checkbox" wide />
|
||||||
|
|
||||||
<InputElement :label="$t('inverteradmin.YieldDayCorrection')"
|
<InputElement :label="$t('inverteradmin.YieldDayCorrection')"
|
||||||
v-model="selectedInverterData.yieldday_correction" type="checkbox"
|
v-model="selectedInverterData.yieldday_correction" type="checkbox"
|
||||||
:tooltip="$t('inverteradmin.YieldDayCorrectionHint')" wide />
|
:tooltip="$t('inverteradmin.YieldDayCorrectionHint')" wide />
|
||||||
|
|||||||
300
webapp/yarn.lock
300
webapp/yarn.lock
@ -161,10 +161,19 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8"
|
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8"
|
||||||
integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==
|
integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==
|
||||||
|
|
||||||
"@eslint/eslintrc@^3.0.2":
|
"@eslint/config-array@^0.15.1":
|
||||||
version "3.0.2"
|
version "0.15.1"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.0.2.tgz#36180f8e85bf34d2fe3ccc2261e8e204a411ab4e"
|
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.15.1.tgz#1fa78b422d98f4e7979f2211a1fde137e26c7d61"
|
||||||
integrity sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==
|
integrity sha512-K4gzNq+yymn/EVsXYmf+SBcBro8MTf+aXJZUphM96CdzUEr+ClGDvAbpmaEK+cGVigVXIgs9gNmvHAlrzzY5JQ==
|
||||||
|
dependencies:
|
||||||
|
"@eslint/object-schema" "^2.1.3"
|
||||||
|
debug "^4.3.1"
|
||||||
|
minimatch "^3.0.5"
|
||||||
|
|
||||||
|
"@eslint/eslintrc@^3.1.0":
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6"
|
||||||
|
integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "^6.12.4"
|
ajv "^6.12.4"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
@ -176,34 +185,25 @@
|
|||||||
minimatch "^3.1.2"
|
minimatch "^3.1.2"
|
||||||
strip-json-comments "^3.1.1"
|
strip-json-comments "^3.1.1"
|
||||||
|
|
||||||
"@eslint/js@9.2.0":
|
"@eslint/js@9.4.0":
|
||||||
version "9.2.0"
|
version "9.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.2.0.tgz#b0a9123e8e91a3d9a2eed3a04a6ed44fdab639aa"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.4.0.tgz#96a2edd37ec0551ce5f9540705be23951c008a0c"
|
||||||
integrity sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==
|
integrity sha512-fdI7VJjP3Rvc70lC4xkFXHB0fiPeojiL1PxVG6t1ZvXQrarj893PweuBTujxDUFk0Fxj4R7PIIAZ/aiiyZPZcg==
|
||||||
|
|
||||||
"@humanwhocodes/config-array@^0.13.0":
|
"@eslint/object-schema@^2.1.3":
|
||||||
version "0.13.0"
|
version "2.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748"
|
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.3.tgz#e65ae80ee2927b4fd8c5c26b15ecacc2b2a6cc2a"
|
||||||
integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==
|
integrity sha512-HAbhAYKfsAC2EkTqve00ibWIZlaU74Z1EHwAjYr4PXF0YU2VEA1zSIKSSpKszRLRWwHzzRZXvK632u+uXzvsvw==
|
||||||
dependencies:
|
|
||||||
"@humanwhocodes/object-schema" "^2.0.3"
|
|
||||||
debug "^4.3.1"
|
|
||||||
minimatch "^3.0.5"
|
|
||||||
|
|
||||||
"@humanwhocodes/module-importer@^1.0.1":
|
"@humanwhocodes/module-importer@^1.0.1":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
|
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
|
||||||
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
|
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
|
||||||
|
|
||||||
"@humanwhocodes/object-schema@^2.0.3":
|
"@humanwhocodes/retry@^0.3.0":
|
||||||
version "2.0.3"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
|
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.0.tgz#6d86b8cb322660f03d3f0aa94b99bdd8e172d570"
|
||||||
integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
|
integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==
|
||||||
|
|
||||||
"@humanwhocodes/retry@^0.2.3":
|
|
||||||
version "0.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.2.3.tgz#c9aa036d1afa643f1250e83150f39efb3a15a631"
|
|
||||||
integrity sha512-X38nUbachlb01YMlvPFojKoiXq+LzZvuSce70KPMPdeM1Rj03k4dR7lDslhbqXn3Ang4EU3+EAmwEAsbrjHW3g==
|
|
||||||
|
|
||||||
"@intlify/bundle-utils@^8.0.0":
|
"@intlify/bundle-utils@^8.0.0":
|
||||||
version "8.0.0"
|
version "8.0.0"
|
||||||
@ -449,10 +449,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
|
||||||
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
|
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
|
||||||
|
|
||||||
"@types/node@^20.12.10":
|
"@types/node@^20.14.2":
|
||||||
version "20.12.10"
|
version "20.14.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.10.tgz#8f0c3f12b0f075eee1fe20c1afb417e9765bef76"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18"
|
||||||
integrity sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==
|
integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~5.26.4"
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
@ -562,32 +562,33 @@
|
|||||||
"@typescript-eslint/types" "7.2.0"
|
"@typescript-eslint/types" "7.2.0"
|
||||||
eslint-visitor-keys "^3.4.1"
|
eslint-visitor-keys "^3.4.1"
|
||||||
|
|
||||||
"@vitejs/plugin-vue@^5.0.4":
|
"@vitejs/plugin-vue@^5.0.5":
|
||||||
version "5.0.4"
|
version "5.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37"
|
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz#e3dc11e427d4b818b7e3202766ad156e3d5e2eaa"
|
||||||
integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==
|
integrity sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==
|
||||||
|
|
||||||
"@volar/language-core@2.2.1", "@volar/language-core@~2.2.0":
|
"@volar/language-core@2.3.0", "@volar/language-core@~2.3.0-alpha.15":
|
||||||
version "2.2.1"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.2.1.tgz#bb4a28f93cd8598a2e2ca1c811ae113a848b5529"
|
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.3.0.tgz#ffb9b64c8b19d7f45b1fdcd9ae9d98d94bad7179"
|
||||||
integrity sha512-iHJAZKcYldZgyS8gx6DfIZApViVBeqbf6iPhqoZpG5A6F4zsZiFldKfwaKaBA3/wnOTWE2i8VUbXywI1WywCPg==
|
integrity sha512-pvhL24WUh3VDnv7Yw5N1sjhPtdx7q9g+Wl3tggmnkMcyK8GcCNElF2zHiKznryn0DiUGk+eez/p2qQhz+puuHw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@volar/source-map" "2.2.1"
|
"@volar/source-map" "2.3.0"
|
||||||
|
|
||||||
"@volar/source-map@2.2.1":
|
"@volar/source-map@2.3.0":
|
||||||
version "2.2.1"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.2.1.tgz#d75b0c38659d3ea7e780d4251ac2b9436845ab97"
|
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.3.0.tgz#faf4df8f10ca40788f03c35eed3e2b7848110cc9"
|
||||||
integrity sha512-w1Bgpguhbp7YTr7VUFu6gb4iAZjeEPsOX4zpgiuvlldbzvIWDWy4t0jVifsIsxZ99HAu+c3swiME7wt+GeNqhA==
|
integrity sha512-G/228aZjAOGhDjhlyZ++nDbKrS9uk+5DMaEstjvzglaAw7nqtDyhnQAsYzUg6BMP9BtwZ59RIw5HGePrutn00Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
muggle-string "^0.4.0"
|
muggle-string "^0.4.0"
|
||||||
|
|
||||||
"@volar/typescript@~2.2.0":
|
"@volar/typescript@~2.3.0-alpha.15":
|
||||||
version "2.2.1"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.2.1.tgz#21585b46cd61c9d63715642ee10418b144b12321"
|
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.3.0.tgz#00306942e95e2e22fed8daf73ec386cd72601ecf"
|
||||||
integrity sha512-Z/tqluR7Hz5/5dCqQp7wo9C/6tSv/IYl+tTzgzUt2NjTq95bKSsuO4E+V06D0c+3aP9x5S9jggLqw451hpnc6Q==
|
integrity sha512-PtUwMM87WsKVeLJN33GSTUjBexlKfKgouWlOUIv7pjrOnTwhXHZNSmpc312xgXdTjQPpToK6KXSIcKu9sBQ5LQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@volar/language-core" "2.2.1"
|
"@volar/language-core" "2.3.0"
|
||||||
path-browserify "^1.0.1"
|
path-browserify "^1.0.1"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
"@vue/compiler-core@3.2.47":
|
"@vue/compiler-core@3.2.47":
|
||||||
version "3.2.47"
|
version "3.2.47"
|
||||||
@ -610,13 +611,13 @@
|
|||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
source-map-js "^1.0.2"
|
source-map-js "^1.0.2"
|
||||||
|
|
||||||
"@vue/compiler-core@3.4.26":
|
"@vue/compiler-core@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.26.tgz#d507886520e83a6f8339ed55ed0b2b5d84b44b73"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz#e69060f4b61429fe57976aa5872cfa21389e4d91"
|
||||||
integrity sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==
|
integrity sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/parser" "^7.24.4"
|
"@babel/parser" "^7.24.4"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
entities "^4.5.0"
|
entities "^4.5.0"
|
||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
source-map-js "^1.2.0"
|
source-map-js "^1.2.0"
|
||||||
@ -629,13 +630,13 @@
|
|||||||
"@vue/compiler-core" "3.2.47"
|
"@vue/compiler-core" "3.2.47"
|
||||||
"@vue/shared" "3.2.47"
|
"@vue/shared" "3.2.47"
|
||||||
|
|
||||||
"@vue/compiler-dom@3.4.26":
|
"@vue/compiler-dom@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz#acc7b788b48152d087d4bb9e655b795e3dbec554"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz#d51d35f40d00ce235d7afc6ad8b09dfd92b1cc1c"
|
||||||
integrity sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==
|
integrity sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-core" "3.4.26"
|
"@vue/compiler-core" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
"@vue/compiler-dom@^3.4.0":
|
"@vue/compiler-dom@^3.4.0":
|
||||||
version "3.4.21"
|
version "3.4.21"
|
||||||
@ -645,16 +646,16 @@
|
|||||||
"@vue/compiler-core" "3.4.21"
|
"@vue/compiler-core" "3.4.21"
|
||||||
"@vue/shared" "3.4.21"
|
"@vue/shared" "3.4.21"
|
||||||
|
|
||||||
"@vue/compiler-sfc@3.4.26":
|
"@vue/compiler-sfc@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz#c679f206829954c3c078d8a9be76d0098b8377ae"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz#399cac1b75c6737bf5440dc9cf3c385bb2959701"
|
||||||
integrity sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==
|
integrity sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/parser" "^7.24.4"
|
"@babel/parser" "^7.24.4"
|
||||||
"@vue/compiler-core" "3.4.26"
|
"@vue/compiler-core" "3.4.27"
|
||||||
"@vue/compiler-dom" "3.4.26"
|
"@vue/compiler-dom" "3.4.27"
|
||||||
"@vue/compiler-ssr" "3.4.26"
|
"@vue/compiler-ssr" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
magic-string "^0.30.10"
|
magic-string "^0.30.10"
|
||||||
postcss "^8.4.38"
|
postcss "^8.4.38"
|
||||||
@ -684,13 +685,13 @@
|
|||||||
"@vue/compiler-dom" "3.2.47"
|
"@vue/compiler-dom" "3.2.47"
|
||||||
"@vue/shared" "3.2.47"
|
"@vue/shared" "3.2.47"
|
||||||
|
|
||||||
"@vue/compiler-ssr@3.4.26":
|
"@vue/compiler-ssr@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz#22842d8adfff972d87bb798b8d496111f7f814b5"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz#2a8ecfef1cf448b09be633901a9c020360472e3d"
|
||||||
integrity sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==
|
integrity sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-dom" "3.4.26"
|
"@vue/compiler-dom" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
"@vue/devtools-api@^6.5.0":
|
"@vue/devtools-api@^6.5.0":
|
||||||
version "6.5.0"
|
version "6.5.0"
|
||||||
@ -711,12 +712,12 @@
|
|||||||
"@typescript-eslint/parser" "^7.1.1"
|
"@typescript-eslint/parser" "^7.1.1"
|
||||||
vue-eslint-parser "^9.3.1"
|
vue-eslint-parser "^9.3.1"
|
||||||
|
|
||||||
"@vue/language-core@2.0.16":
|
"@vue/language-core@2.0.21":
|
||||||
version "2.0.16"
|
version "2.0.21"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.0.16.tgz#c059228e6a0a17b4505421da0e5747a4a04facbe"
|
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.0.21.tgz#882667d0c9f07bc884f163e75eed666234df77fe"
|
||||||
integrity sha512-Bc2sexRH99pznOph8mLw2BlRZ9edm7tW51kcBXgx8adAoOcZUWJj3UNSsdQ6H9Y8meGz7BoazVrVo/jUukIsPw==
|
integrity sha512-vjs6KwnCK++kIXT+eI63BGpJHfHNVJcUCr3RnvJsccT3vbJnZV5IhHR2puEkoOkIbDdp0Gqi1wEnv3hEd3WsxQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@volar/language-core" "~2.2.0"
|
"@volar/language-core" "~2.3.0-alpha.15"
|
||||||
"@vue/compiler-dom" "^3.4.0"
|
"@vue/compiler-dom" "^3.4.0"
|
||||||
"@vue/shared" "^3.4.0"
|
"@vue/shared" "^3.4.0"
|
||||||
computeds "^0.0.1"
|
computeds "^0.0.1"
|
||||||
@ -735,37 +736,37 @@
|
|||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
magic-string "^0.25.7"
|
magic-string "^0.25.7"
|
||||||
|
|
||||||
"@vue/reactivity@3.4.26":
|
"@vue/reactivity@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.26.tgz#1191f543809d4c93e5b3e842ba83022350a3f205"
|
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.27.tgz#6ece72331bf719953f5eaa95ec60b2b8d49e3791"
|
||||||
integrity sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==
|
integrity sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
"@vue/runtime-core@3.4.26":
|
"@vue/runtime-core@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.26.tgz#51ee971cb700370a67e5a510c4a84eff7491d658"
|
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz#1b6e1d71e4604ba7442dd25ed22e4a1fc6adbbda"
|
||||||
integrity sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==
|
integrity sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/reactivity" "3.4.26"
|
"@vue/reactivity" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
"@vue/runtime-dom@3.4.26":
|
"@vue/runtime-dom@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz#179aa7c8dc964112e6d096bc8ec5f361111009a1"
|
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz#fe8d1ce9bbe8921d5dd0ad5c10df0e04ef7a5ee7"
|
||||||
integrity sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==
|
integrity sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/runtime-core" "3.4.26"
|
"@vue/runtime-core" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
csstype "^3.1.3"
|
csstype "^3.1.3"
|
||||||
|
|
||||||
"@vue/server-renderer@3.4.26":
|
"@vue/server-renderer@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.26.tgz#6d0c6b0366bfe0232579aea00e3ff6784e5a1c60"
|
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz#3306176f37e648ba665f97dda3ce705687be63d2"
|
||||||
integrity sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==
|
integrity sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-ssr" "3.4.26"
|
"@vue/compiler-ssr" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
"@vue/shared@3.2.47":
|
"@vue/shared@3.2.47":
|
||||||
version "3.2.47"
|
version "3.2.47"
|
||||||
@ -777,10 +778,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.21.tgz#de526a9059d0a599f0b429af7037cd0c3ed7d5a1"
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.21.tgz#de526a9059d0a599f0b429af7037cd0c3ed7d5a1"
|
||||||
integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==
|
integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==
|
||||||
|
|
||||||
"@vue/shared@3.4.26":
|
"@vue/shared@3.4.27":
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.26.tgz#f17854fb1faf889854aed4b23b60e86a8cab6403"
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.27.tgz#f05e3cd107d157354bb4ae7a7b5fc9cf73c63b50"
|
||||||
integrity sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==
|
integrity sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==
|
||||||
|
|
||||||
"@vue/tsconfig@^0.5.1":
|
"@vue/tsconfig@^0.5.1":
|
||||||
version "0.5.1"
|
version "0.5.1"
|
||||||
@ -1158,10 +1159,10 @@ escodegen@^2.1.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-plugin-vue@^9.25.0:
|
eslint-plugin-vue@^9.26.0:
|
||||||
version "9.25.0"
|
version "9.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz#615cb7bb6d0e2140d21840b9aa51dce69e803e7a"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz#bf7f5cce62c8f878059b91edae44d22974133af5"
|
||||||
integrity sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==
|
integrity sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/eslint-utils" "^4.4.0"
|
"@eslint-community/eslint-utils" "^4.4.0"
|
||||||
globals "^13.24.0"
|
globals "^13.24.0"
|
||||||
@ -1208,18 +1209,18 @@ eslint-visitor-keys@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb"
|
||||||
integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==
|
integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==
|
||||||
|
|
||||||
eslint@^9.2.0:
|
eslint@^9.4.0:
|
||||||
version "9.2.0"
|
version "9.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.2.0.tgz#0700ebc99528753315d78090876911d3cdbf19fe"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.4.0.tgz#79150c3610ae606eb131f1d648d5f43b3d45f3cd"
|
||||||
integrity sha512-0n/I88vZpCOzO+PQpt0lbsqmn9AsnsJAQseIqhZFI8ibQT0U1AkEKRxA3EVMos0BoHSXDQvCXY25TUjB5tr8Og==
|
integrity sha512-sjc7Y8cUD1IlwYcTS9qPSvGjAC8Ne9LctpxKKu3x/1IC9bnOg98Zy6GxEJUfr1NojMgVPlyANXYns8oE2c1TAA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/eslint-utils" "^4.2.0"
|
"@eslint-community/eslint-utils" "^4.2.0"
|
||||||
"@eslint-community/regexpp" "^4.6.1"
|
"@eslint-community/regexpp" "^4.6.1"
|
||||||
"@eslint/eslintrc" "^3.0.2"
|
"@eslint/config-array" "^0.15.1"
|
||||||
"@eslint/js" "9.2.0"
|
"@eslint/eslintrc" "^3.1.0"
|
||||||
"@humanwhocodes/config-array" "^0.13.0"
|
"@eslint/js" "9.4.0"
|
||||||
"@humanwhocodes/module-importer" "^1.0.1"
|
"@humanwhocodes/module-importer" "^1.0.1"
|
||||||
"@humanwhocodes/retry" "^0.2.3"
|
"@humanwhocodes/retry" "^0.3.0"
|
||||||
"@nodelib/fs.walk" "^1.2.8"
|
"@nodelib/fs.walk" "^1.2.8"
|
||||||
ajv "^6.12.4"
|
ajv "^6.12.4"
|
||||||
chalk "^4.0.0"
|
chalk "^4.0.0"
|
||||||
@ -2201,10 +2202,10 @@ safe-regex-test@^1.0.0:
|
|||||||
get-intrinsic "^1.1.3"
|
get-intrinsic "^1.1.3"
|
||||||
is-regex "^1.1.4"
|
is-regex "^1.1.4"
|
||||||
|
|
||||||
sass@^1.76.0:
|
sass@^1.77.4:
|
||||||
version "1.76.0"
|
version "1.77.4"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.76.0.tgz#fe15909500735ac154f0dc7386d656b62b03987d"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.4.tgz#92059c7bfc56b827c56eb116778d157ec017a5cd"
|
||||||
integrity sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==
|
integrity sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
immutable "^4.0.0"
|
immutable "^4.0.0"
|
||||||
@ -2406,10 +2407,10 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
terser@^5.31.0:
|
terser@^5.31.1:
|
||||||
version "5.31.0"
|
version "5.31.1"
|
||||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.0.tgz#06eef86f17007dbad4593f11a574c7f5eb02c6a1"
|
resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.1.tgz#735de3c987dd671e95190e6b98cfe2f07f3cf0d4"
|
||||||
integrity sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==
|
integrity sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/source-map" "^0.3.3"
|
"@jridgewell/source-map" "^0.3.3"
|
||||||
acorn "^8.8.2"
|
acorn "^8.8.2"
|
||||||
@ -2519,10 +2520,10 @@ vite-plugin-css-injected-by-js@^3.5.1:
|
|||||||
resolved "https://registry.yarnpkg.com/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.5.1.tgz#b9c568c21b131d08e31aa6d368ee39c9d6c1b6c1"
|
resolved "https://registry.yarnpkg.com/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.5.1.tgz#b9c568c21b131d08e31aa6d368ee39c9d6c1b6c1"
|
||||||
integrity sha512-9ioqwDuEBxW55gNoWFEDhfLTrVKXEEZgl5adhWmmqa88EQGKfTmexy4v1Rh0pAS6RhKQs2bUYQArprB32JpUZQ==
|
integrity sha512-9ioqwDuEBxW55gNoWFEDhfLTrVKXEEZgl5adhWmmqa88EQGKfTmexy4v1Rh0pAS6RhKQs2bUYQArprB32JpUZQ==
|
||||||
|
|
||||||
vite@^5.2.11:
|
vite@^5.2.13:
|
||||||
version "5.2.11"
|
version "5.2.13"
|
||||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.11.tgz#726ec05555431735853417c3c0bfb36003ca0cbd"
|
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.13.tgz#945ababcbe3d837ae2479c29f661cd20bc5e1a80"
|
||||||
integrity sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==
|
integrity sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild "^0.20.1"
|
esbuild "^0.20.1"
|
||||||
postcss "^8.4.38"
|
postcss "^8.4.38"
|
||||||
@ -2530,6 +2531,11 @@ vite@^5.2.11:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.3"
|
fsevents "~2.3.3"
|
||||||
|
|
||||||
|
vscode-uri@^3.0.8:
|
||||||
|
version "3.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
|
||||||
|
integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
|
||||||
|
|
||||||
vue-eslint-parser@^9.3.1:
|
vue-eslint-parser@^9.3.1:
|
||||||
version "9.3.1"
|
version "9.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz#429955e041ae5371df5f9e37ebc29ba046496182"
|
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz#429955e041ae5371df5f9e37ebc29ba046496182"
|
||||||
@ -2565,10 +2571,10 @@ vue-i18n@^9.13.1:
|
|||||||
"@intlify/shared" "9.13.1"
|
"@intlify/shared" "9.13.1"
|
||||||
"@vue/devtools-api" "^6.5.0"
|
"@vue/devtools-api" "^6.5.0"
|
||||||
|
|
||||||
vue-router@^4.3.2:
|
vue-router@^4.3.3:
|
||||||
version "4.3.2"
|
version "4.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.3.2.tgz#08096c7765dacc6832f58e35f7a081a8b34116a7"
|
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.3.3.tgz#7505509d429a36694b12ba1f6530016c5ce5f6bf"
|
||||||
integrity sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==
|
integrity sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/devtools-api" "^6.5.1"
|
"@vue/devtools-api" "^6.5.1"
|
||||||
|
|
||||||
@ -2580,25 +2586,25 @@ vue-template-compiler@^2.7.14:
|
|||||||
de-indent "^1.0.2"
|
de-indent "^1.0.2"
|
||||||
he "^1.2.0"
|
he "^1.2.0"
|
||||||
|
|
||||||
vue-tsc@^2.0.16:
|
vue-tsc@^2.0.21:
|
||||||
version "2.0.16"
|
version "2.0.21"
|
||||||
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.0.16.tgz#ba82c4cdac283e8e39e30e817c8c1c967e528358"
|
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.0.21.tgz#c574a2c20e8a5e5643af546c6051319cdf983239"
|
||||||
integrity sha512-/gHAWJa216PeEhfxtAToIbxdWgw01wuQzo48ZUqMYVEyNqDp+OYV9xMO5HaPS2P3Ls0+EsjguMZLY4cGobX4Ew==
|
integrity sha512-E6x1p1HaHES6Doy8pqtm7kQern79zRtIewkf9fiv7Y43Zo4AFDS5hKi+iHi2RwEhqRmuiwliB1LCEFEGwvxQnw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@volar/typescript" "~2.2.0"
|
"@volar/typescript" "~2.3.0-alpha.15"
|
||||||
"@vue/language-core" "2.0.16"
|
"@vue/language-core" "2.0.21"
|
||||||
semver "^7.5.4"
|
semver "^7.5.4"
|
||||||
|
|
||||||
vue@^3.4.26:
|
vue@^3.4.27:
|
||||||
version "3.4.26"
|
version "3.4.27"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.26.tgz#936c97e37672c737705d7bdfa62c31af18742269"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.27.tgz#40b7d929d3e53f427f7f5945386234d2854cc2a1"
|
||||||
integrity sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==
|
integrity sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-dom" "3.4.26"
|
"@vue/compiler-dom" "3.4.27"
|
||||||
"@vue/compiler-sfc" "3.4.26"
|
"@vue/compiler-sfc" "3.4.27"
|
||||||
"@vue/runtime-dom" "3.4.26"
|
"@vue/runtime-dom" "3.4.27"
|
||||||
"@vue/server-renderer" "3.4.26"
|
"@vue/server-renderer" "3.4.27"
|
||||||
"@vue/shared" "3.4.26"
|
"@vue/shared" "3.4.27"
|
||||||
|
|
||||||
webpack-sources@^3.2.3:
|
webpack-sources@^3.2.3:
|
||||||
version "3.2.3"
|
version "3.2.3"
|
||||||
|
|||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user