Merge branch 'master' of https://github.com/tbnobody/OpenDTU into Database
This commit is contained in:
commit
06f4e64f2c
@ -5,7 +5,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#define CONFIG_FILENAME "/config.json"
|
||||
#define CONFIG_VERSION 0x00011900 // 0.1.24 // make sure to clean all after change
|
||||
#define CONFIG_VERSION 0x00011a00 // 0.1.26 // make sure to clean all after change
|
||||
|
||||
#define WIFI_MAX_SSID_STRLEN 32
|
||||
#define WIFI_MAX_PASSWORD_STRLEN 64
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <cstdint>
|
||||
|
||||
class Utils {
|
||||
@ -9,4 +10,5 @@ public:
|
||||
static uint64_t generateDtuSerial();
|
||||
static int getTimezoneOffset();
|
||||
static void restartDtu();
|
||||
static bool checkJsonAlloc(const DynamicJsonDocument& doc, const char* function, const uint16_t line);
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "WebApi_device.h"
|
||||
#include "WebApi_devinfo.h"
|
||||
#include "WebApi_dtu.h"
|
||||
#include "WebApi_errors.h"
|
||||
#include "WebApi_eventlog.h"
|
||||
#include "WebApi_firmware.h"
|
||||
#include "WebApi_gridprofile.h"
|
||||
@ -35,6 +36,8 @@ public:
|
||||
|
||||
static void sendTooManyRequests(AsyncWebServerRequest* request);
|
||||
|
||||
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ enum WebApiError {
|
||||
GenericDataTooLarge,
|
||||
GenericParseError,
|
||||
GenericValueMissing,
|
||||
GenericWriteFailed,
|
||||
|
||||
DtuBase = 2000,
|
||||
DtuSerialZero,
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#define AUTH_USERNAME "admin"
|
||||
#define SECURITY_ALLOW_READONLY true
|
||||
|
||||
#define WIFI_RECONNECT_TIMEOUT 15
|
||||
#define WIFI_RECONNECT_TIMEOUT 30
|
||||
#define WIFI_RECONNECT_REDO_TIMEOUT 600
|
||||
|
||||
#define WIFI_SSID ""
|
||||
|
||||
@ -24,6 +24,7 @@ platform = espressif32@6.5.0
|
||||
build_flags =
|
||||
-DPIOENV=\"$PIOENV\"
|
||||
-D_TASK_STD_FUNCTION=1
|
||||
-D_TASK_THREAD_SAFE=1
|
||||
-Wall -Wextra -Wunused -Wmisleading-indentation -Wduplicated-cond -Wlogical-op -Wnull-dereference
|
||||
; Have to remove -Werror because of
|
||||
; https://github.com/espressif/arduino-esp32/issues/9044 and
|
||||
|
||||
@ -4,9 +4,11 @@
|
||||
*/
|
||||
#include "Configuration.h"
|
||||
#include "MessageOutput.h"
|
||||
#include "Utils.h"
|
||||
#include "defaults.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <LittleFS.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
CONFIG_T config;
|
||||
|
||||
@ -25,6 +27,10 @@ bool ConfigurationClass::write()
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonObject cfg = doc.createNestedObject("cfg");
|
||||
cfg["version"] = config.Cfg.Version;
|
||||
cfg["save_count"] = config.Cfg.SaveCount;
|
||||
@ -150,6 +156,11 @@ bool ConfigurationClass::read()
|
||||
File f = LittleFS.open(CONFIG_FILENAME, "r", false);
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deserialize the JSON document
|
||||
const DeserializationError error = deserializeJson(doc, f);
|
||||
if (error) {
|
||||
@ -310,6 +321,11 @@ void ConfigurationClass::migrate()
|
||||
}
|
||||
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
|
||||
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deserialize the JSON document
|
||||
const DeserializationError error = deserializeJson(doc, f);
|
||||
if (error) {
|
||||
@ -339,6 +355,14 @@ void ConfigurationClass::migrate()
|
||||
config.Dtu.Nrf.PaLevel = dtu["pa_level"];
|
||||
}
|
||||
|
||||
if (config.Cfg.Version < 0x00011a00) {
|
||||
// This migration fixes this issue: https://github.com/espressif/arduino-esp32/issues/8828
|
||||
// It occours when migrating from Core 2.0.9 to 2.0.14
|
||||
// which was done by updating ESP32 PlatformIO from 6.3.2 to 6.5.0
|
||||
nvs_flash_erase();
|
||||
nvs_flash_init();
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
config.Cfg.Version = CONFIG_VERSION;
|
||||
|
||||
@ -135,6 +135,10 @@ void MqttHandleHassClass::publishInverterField(std::shared_ptr<InverterAbstract>
|
||||
}
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = name;
|
||||
root["stat_t"] = stateTopic;
|
||||
root["uniq_id"] = serial + "_ch" + chanNum + "_" + fieldName;
|
||||
@ -179,6 +183,10 @@ void MqttHandleHassClass::publishInverterButton(std::shared_ptr<InverterAbstract
|
||||
const String cmdTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = caption;
|
||||
root["uniq_id"] = serial + "_" + buttonId;
|
||||
if (strcmp(icon, "")) {
|
||||
@ -217,6 +225,10 @@ void MqttHandleHassClass::publishInverterNumber(
|
||||
const String statTopic = MqttSettings.getPrefix() + serial + "/" + stateTopic;
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = caption;
|
||||
root["uniq_id"] = serial + "_" + buttonId;
|
||||
if (strcmp(icon, "")) {
|
||||
@ -251,6 +263,10 @@ void MqttHandleHassClass::publishInverterBinarySensor(std::shared_ptr<InverterAb
|
||||
const String statTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = caption;
|
||||
root["uniq_id"] = serial + "_" + sensorId;
|
||||
root["stat_t"] = statTopic;
|
||||
@ -275,6 +291,10 @@ void MqttHandleHassClass::publishDtuSensor(const char* name, const char* device_
|
||||
}
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = name;
|
||||
root["uniq_id"] = getDtuUniqueId() + "_" + id;
|
||||
if (strcmp(device_class, "")) {
|
||||
@ -317,6 +337,10 @@ void MqttHandleHassClass::publishDtuBinarySensor(const char* name, const char* d
|
||||
}
|
||||
|
||||
DynamicJsonDocument root(1024);
|
||||
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
root["name"] = name;
|
||||
root["uniq_id"] = getDtuUniqueId() + "_" + id;
|
||||
root["stat_t"] = MqttSettings.getPrefix() + topic;
|
||||
|
||||
@ -268,7 +268,8 @@ void NetworkSettingsClass::applyConfig()
|
||||
MessageOutput.print("new credentials... ");
|
||||
WiFi.begin(
|
||||
Configuration.get().WiFi.Ssid,
|
||||
Configuration.get().WiFi.Password);
|
||||
Configuration.get().WiFi.Password,
|
||||
WIFI_ALL_CHANNEL_SCAN);
|
||||
} else {
|
||||
MessageOutput.print("existing credentials... ");
|
||||
WiFi.begin();
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "Utils.h"
|
||||
#include "Display_Graphic.h"
|
||||
#include "Led_Single.h"
|
||||
#include "MessageOutput.h"
|
||||
#include <Esp.h>
|
||||
|
||||
uint32_t Utils::getChipId()
|
||||
@ -65,3 +66,13 @@ void Utils::restartDtu()
|
||||
yield();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
bool Utils::checkJsonAlloc(const DynamicJsonDocument& doc, const char* function, const uint16_t line)
|
||||
{
|
||||
if (doc.capacity() == 0) {
|
||||
MessageOutput.printf("Alloc failed: %s, %d\r\n", function, line);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -103,4 +103,16 @@ void WebApiClass::sendTooManyRequests(AsyncWebServerRequest* request)
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void WebApiClass::writeConfig(JsonVariant& retMsg, const WebApiError code, const String& message)
|
||||
{
|
||||
if (!Configuration.write()) {
|
||||
retMsg["message"] = "Write failed!";
|
||||
retMsg["code"] = WebApiError::GenericWriteFailed;
|
||||
} else {
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = message;
|
||||
retMsg["code"] = code;
|
||||
}
|
||||
}
|
||||
|
||||
WebApiClass WebApi;
|
||||
@ -59,7 +59,7 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -125,8 +125,8 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
JsonArray data = root.createNestedArray("configs");
|
||||
auto& root = response->getRoot();
|
||||
auto data = root.createNestedArray("configs");
|
||||
|
||||
File rootfs = LittleFS.open("/");
|
||||
File file = rootfs.openNextFile();
|
||||
|
||||
@ -33,14 +33,14 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
const PinMapping_t& pin = PinMapping.get();
|
||||
|
||||
JsonObject curPin = root.createNestedObject("curPin");
|
||||
auto curPin = root.createNestedObject("curPin");
|
||||
curPin["name"] = config.Dev_PinMapping;
|
||||
|
||||
JsonObject nrfPinObj = curPin.createNestedObject("nrf24");
|
||||
auto nrfPinObj = curPin.createNestedObject("nrf24");
|
||||
nrfPinObj["clk"] = pin.nrf24_clk;
|
||||
nrfPinObj["cs"] = pin.nrf24_cs;
|
||||
nrfPinObj["en"] = pin.nrf24_en;
|
||||
@ -48,7 +48,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
nrfPinObj["miso"] = pin.nrf24_miso;
|
||||
nrfPinObj["mosi"] = pin.nrf24_mosi;
|
||||
|
||||
JsonObject cmtPinObj = curPin.createNestedObject("cmt");
|
||||
auto cmtPinObj = curPin.createNestedObject("cmt");
|
||||
cmtPinObj["clk"] = pin.cmt_clk;
|
||||
cmtPinObj["cs"] = pin.cmt_cs;
|
||||
cmtPinObj["fcs"] = pin.cmt_fcs;
|
||||
@ -56,7 +56,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
cmtPinObj["gpio2"] = pin.cmt_gpio2;
|
||||
cmtPinObj["gpio3"] = pin.cmt_gpio3;
|
||||
|
||||
JsonObject ethPinObj = curPin.createNestedObject("eth");
|
||||
auto ethPinObj = curPin.createNestedObject("eth");
|
||||
ethPinObj["enabled"] = pin.eth_enabled;
|
||||
ethPinObj["phy_addr"] = pin.eth_phy_addr;
|
||||
ethPinObj["power"] = pin.eth_power;
|
||||
@ -65,19 +65,19 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
ethPinObj["type"] = pin.eth_type;
|
||||
ethPinObj["clk_mode"] = pin.eth_clk_mode;
|
||||
|
||||
JsonObject displayPinObj = curPin.createNestedObject("display");
|
||||
auto displayPinObj = curPin.createNestedObject("display");
|
||||
displayPinObj["type"] = pin.display_type;
|
||||
displayPinObj["data"] = pin.display_data;
|
||||
displayPinObj["clk"] = pin.display_clk;
|
||||
displayPinObj["cs"] = pin.display_cs;
|
||||
displayPinObj["reset"] = pin.display_reset;
|
||||
|
||||
JsonObject ledPinObj = curPin.createNestedObject("led");
|
||||
auto ledPinObj = curPin.createNestedObject("led");
|
||||
for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) {
|
||||
ledPinObj["led" + String(i)] = pin.led[i];
|
||||
}
|
||||
|
||||
JsonObject display = root.createNestedObject("display");
|
||||
auto display = root.createNestedObject("display");
|
||||
display["rotation"] = config.Display.Rotation;
|
||||
display["power_safe"] = config.Display.PowerSafe;
|
||||
display["screensaver"] = config.Display.ScreenSaver;
|
||||
@ -85,9 +85,9 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
display["language"] = config.Display.Language;
|
||||
display["diagramduration"] = config.Display.DiagramDuration;
|
||||
|
||||
JsonArray leds = root.createNestedArray("led");
|
||||
auto leds = root.createNestedArray("led");
|
||||
for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) {
|
||||
JsonObject led = leds.createNestedObject();
|
||||
auto led = leds.createNestedObject();
|
||||
led["brightness"] = config.Led_Single[i].Brightness;
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -175,11 +175,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
||||
Display.setLanguage(config.Display.Language);
|
||||
Display.Diagram().updatePeriod();
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -28,7 +28,7 @@ void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
uint64_t serial = 0;
|
||||
if (request->hasParam("inv")) {
|
||||
|
||||
@ -30,7 +30,7 @@ void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
// DTU Serial is read as HEX
|
||||
@ -57,7 +57,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -154,11 +154,8 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
||||
config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as<uint8_t>();
|
||||
config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as<int8_t>();
|
||||
config.Dtu.Cmt.Frequency = root["cmt_frequency"].as<uint32_t>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -27,7 +27,7 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 2048);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
uint64_t serial = 0;
|
||||
if (request->hasParam("inv")) {
|
||||
|
||||
@ -28,7 +28,7 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
uint64_t serial = 0;
|
||||
if (request->hasParam("inv")) {
|
||||
@ -72,7 +72,7 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
uint64_t serial = 0;
|
||||
if (request->hasParam("inv")) {
|
||||
|
||||
@ -36,7 +36,7 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 768 * INV_MAX_COUNT);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
JsonArray data = root.createNestedArray("inverter");
|
||||
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
@ -94,7 +94,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -167,11 +167,8 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
|
||||
inverter->Serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
strncpy(inverter->Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter created!";
|
||||
retMsg["code"] = WebApiError::InverterAdded;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterAdded, "Inverter created!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -194,7 +191,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -294,11 +291,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
arrayCount++;
|
||||
}
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["code"] = WebApiError::InverterChanged;
|
||||
retMsg["message"] = "Inverter changed!";
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterChanged, "Inverter changed!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -340,7 +333,7 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -395,11 +388,8 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
|
||||
|
||||
inverter.Serial = 0;
|
||||
strncpy(inverter.Name, "", sizeof(inverter.Name));
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter deleted!";
|
||||
retMsg["code"] = WebApiError::InverterDeleted;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterDeleted, "Inverter deleted!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -414,7 +404,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -466,11 +456,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
|
||||
order++;
|
||||
}
|
||||
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Inverter order saved!";
|
||||
retMsg["code"] = WebApiError::InverterOrdered;
|
||||
WebApi.writeConfig(retMsg, WebApiError::InverterOrdered, "Inverter order saved!");
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -31,7 +31,7 @@ void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
||||
auto inv = Hoymiles.getInverterByPos(i);
|
||||
@ -64,7 +64,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
|
||||
@ -29,7 +29,7 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
|
||||
@ -33,7 +33,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
||||
@ -67,7 +67,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
||||
@ -105,7 +105,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -334,11 +334,8 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
||||
config.Mqtt.Hass.Retain = root["mqtt_hass_retain"].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));
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -32,7 +32,7 @@ void WebApiNetworkClass::onNetworkStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
root["sta_status"] = ((WiFi.getMode() & WIFI_STA) != 0);
|
||||
root["sta_ssid"] = WiFi.SSID();
|
||||
@ -63,7 +63,7 @@ void WebApiNetworkClass::onNetworkAdminGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["hostname"] = config.WiFi.Hostname;
|
||||
@ -89,7 +89,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -238,11 +238,8 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
config.WiFi.ApTimeout = root["aptimeout"].as<uint>();
|
||||
config.Mdns.Enabled = root["mdnsenabled"].as<bool>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@ -35,7 +35,7 @@ void WebApiNtpClass::onNtpStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["ntp_server"] = config.Ntp.Server;
|
||||
@ -80,7 +80,7 @@ void WebApiNtpClass::onNtpAdminGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["ntp_server"] = config.Ntp.Server;
|
||||
@ -101,7 +101,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -179,11 +179,8 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request)
|
||||
config.Ntp.Latitude = root["latitude"].as<double>();
|
||||
config.Ntp.Longitude = root["longitude"].as<double>();
|
||||
config.Ntp.SunsetType = root["sunsettype"].as<uint8_t>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -201,7 +198,7 @@ void WebApiNtpClass::onNtpTimeGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo, 5)) {
|
||||
@ -228,7 +225,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
|
||||
@ -29,7 +29,7 @@ void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
||||
auto inv = Hoymiles.getInverterByPos(i);
|
||||
@ -57,7 +57,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
|
||||
@ -31,7 +31,7 @@ void WebApiSecurityClass::onSecurityGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
root["password"] = config.Security.Password;
|
||||
@ -48,7 +48,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "warning";
|
||||
|
||||
if (!request->hasParam("data", true)) {
|
||||
@ -101,11 +101,8 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
||||
CONFIG_T& config = Configuration.get();
|
||||
strlcpy(config.Security.Password, root["password"].as<String>().c_str(), sizeof(config.Security.Password));
|
||||
config.Security.AllowReadonly = root["allow_readonly"].as<bool>();
|
||||
Configuration.write();
|
||||
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Settings saved!";
|
||||
retMsg["code"] = WebApiError::GenericSuccess;
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@ -118,7 +115,7 @@ void WebApiSecurityClass::onAuthenticateGet(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject retMsg = response->getRoot();
|
||||
auto& retMsg = response->getRoot();
|
||||
retMsg["type"] = "success";
|
||||
retMsg["message"] = "Authentication successful!";
|
||||
retMsg["code"] = WebApiError::SecurityAuthSuccess;
|
||||
|
||||
@ -36,7 +36,7 @@ void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
root["hostname"] = NetworkSettings.getHostname();
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "Configuration.h"
|
||||
#include "Datastore.h"
|
||||
#include "MessageOutput.h"
|
||||
#include "Utils.h"
|
||||
#include "WebApi.h"
|
||||
#include "defaults.h"
|
||||
#include <AsyncJson.h>
|
||||
@ -64,11 +65,11 @@ void WebApiWsLiveClass::loop()
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
DynamicJsonDocument root(4096 * INV_MAX_COUNT);
|
||||
JsonVariant var = root;
|
||||
generateJsonResponse(var);
|
||||
if (Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||
JsonVariant var = root;
|
||||
generateJsonResponse(var);
|
||||
|
||||
String buffer;
|
||||
if (buffer) {
|
||||
String buffer;
|
||||
serializeJson(root, buffer);
|
||||
|
||||
if (Configuration.get().Security.AllowReadonly) {
|
||||
@ -221,7 +222,7 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096 * INV_MAX_COUNT);
|
||||
JsonVariant root = response->getRoot();
|
||||
auto& root = response->getRoot();
|
||||
|
||||
generateJsonResponse(root);
|
||||
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
"mitt": "^3.0.1",
|
||||
"sortablejs": "^1.15.1",
|
||||
"spark-md5": "^3.0.2",
|
||||
"tippy.js": "^6.3.7",
|
||||
"vue": "^3.4.3",
|
||||
"vue-google-charts": "^1.1.0",
|
||||
"vue": "^3.4.5",
|
||||
"vue-i18n": "^9.8.0",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue3-calendar-heatmap": "^2.0.5"
|
||||
@ -39,7 +37,7 @@
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"sass": "^1.69.6",
|
||||
"sass": "^1.69.7",
|
||||
"terser": "^5.26.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.10",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Daten zu groß!",
|
||||
"1004": "Fehler beim interpretieren der Daten!",
|
||||
"1005": "Benötigte Werte fehlen!",
|
||||
"1006": "Schreiben fehlgeschlagen!",
|
||||
"2001": "Die Seriennummer darf nicht 0 sein!",
|
||||
"2002": "Das Abfraginterval muss größer als 0 sein!",
|
||||
"2003": "Ungültige Sendeleistung angegeben!",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Data too large!",
|
||||
"1004": "Failed to parse data!",
|
||||
"1005": "Values are missing!",
|
||||
"1006": "Write failed!",
|
||||
"2001": "Serial cannot be zero!",
|
||||
"2002": "Poll interval must be greater zero!",
|
||||
"2003": "Invalid power level setting!",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"1003": "Données trop importantes !",
|
||||
"1004": "Échec de l'analyse des données !",
|
||||
"1005": "Certaines valeurs sont manquantes !",
|
||||
"1006": "Write failed!",
|
||||
"2001": "Le numéro de série ne peut pas être nul !",
|
||||
"2002": "L'intervalle de sondage doit être supérieur à zéro !",
|
||||
"2003": "Réglage du niveau de puissance invalide !",
|
||||
|
||||
130
webapp/yarn.lock
130
webapp/yarn.lock
@ -569,13 +569,13 @@
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
"@vue/compiler-core@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.3.tgz#8e8f88273f061cf0a49bf958255f5f0621f12d8b"
|
||||
integrity sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==
|
||||
"@vue/compiler-core@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.5.tgz#9565aebaadef8649eb7c8e150a5f4f4e2542667d"
|
||||
integrity sha512-Daka7P1z2AgKjzuueWXhwzIsKu0NkLB6vGbNVEV2iJ8GJTrzraZo/Sk4GWCMRtd/qVi3zwnk+Owbd/xSZbwHtQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.23.6"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/shared" "3.4.5"
|
||||
entities "^4.5.0"
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.0.2"
|
||||
@ -588,13 +588,13 @@
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/compiler-dom@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.3.tgz#bea8acde9585d5ce92a3f11c062c863fb33e44d7"
|
||||
integrity sha512-oGF1E9/htI6JWj/lTJgr6UgxNCtNHbM6xKVreBWeZL9QhRGABRVoWGAzxmtBfSOd+w0Zi5BY0Es/tlJrN6WgEg==
|
||||
"@vue/compiler-dom@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.5.tgz#c53c9d7715b777b1d6d2adcbc491bfd4f9510edd"
|
||||
integrity sha512-J8YlxknJVd90SXFJ4HwGANSAXsx5I0lK30sO/zvYV7s5gXf7gZR7r/1BmZ2ju7RGH1lnc6bpBc6nL61yW+PsAQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/compiler-core" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
"@vue/compiler-dom@^3.3.0":
|
||||
version "3.3.2"
|
||||
@ -604,16 +604,16 @@
|
||||
"@vue/compiler-core" "3.3.2"
|
||||
"@vue/shared" "3.3.2"
|
||||
|
||||
"@vue/compiler-sfc@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.3.tgz#a9d35b2deef38576dedd9938851c032fb2ca8617"
|
||||
integrity sha512-NuJqb5is9I4uzv316VRUDYgIlPZCG8D+ARt5P4t5UDShIHKL25J3TGZAUryY/Aiy0DsY7srJnZL5ryB6DD63Zw==
|
||||
"@vue/compiler-sfc@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.5.tgz#f93f986dfc5c7f72b9a5e00b48be75d9116cc948"
|
||||
integrity sha512-jauvkDuSSUbP0ebhfNqljhShA90YEfX/0wZ+w40oZF43IjGyWYjqYaJbvMJwGOd+9+vODW6eSvnk28f0SGV7OQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.23.6"
|
||||
"@vue/compiler-core" "3.4.3"
|
||||
"@vue/compiler-dom" "3.4.3"
|
||||
"@vue/compiler-ssr" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/compiler-core" "3.4.5"
|
||||
"@vue/compiler-dom" "3.4.5"
|
||||
"@vue/compiler-ssr" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.30.5"
|
||||
postcss "^8.4.32"
|
||||
@ -643,13 +643,13 @@
|
||||
"@vue/compiler-dom" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/compiler-ssr@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.3.tgz#c3f641a15a04893b5bc3278f3dac65bed44dce1d"
|
||||
integrity sha512-wnYQtMBkeFSxgSSQbYGQeXPhQacQiog2c6AlvMldQH6DB+gSXK/0F6DVXAJfEiuBSgBhUc8dwrrG5JQcqwalsA==
|
||||
"@vue/compiler-ssr@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.5.tgz#d412a4c9b10d69172a5ce0ec78de98dad441a58d"
|
||||
integrity sha512-DDdEcDzj2lWTMfUMMtEpLDhURai9LhM0zSZ219jCt7b2Vyl0/jy3keFgCPMitG0V1S1YG4Cmws3lWHWdxHQOpg==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/compiler-dom" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
"@vue/devtools-api@^6.5.0":
|
||||
version "6.5.1"
|
||||
@ -691,37 +691,37 @@
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/reactivity@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.3.tgz#95287b5950b328df4a942a7cf14a0e13487f1eac"
|
||||
integrity sha512-q5f9HLDU+5aBKizXHAx0w4whkIANs1Muiq9R5YXm0HtorSlflqv9u/ohaMxuuhHWCji4xqpQ1eL04WvmAmGnFg==
|
||||
"@vue/reactivity@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.5.tgz#68bc91cd356eed95dc5e9e0570e3f7becaee578b"
|
||||
integrity sha512-BcWkKvjdvqJwb7BhhFkXPLDCecX4d4a6GATvCduJQDLv21PkPowAE5GKuIE5p6RC07/Lp9FMkkq4AYCTVF5KlQ==
|
||||
dependencies:
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
"@vue/runtime-core@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.3.tgz#fe7649a93d9b20b9b351cd699f69f0e34a26e3ab"
|
||||
integrity sha512-C1r6QhB1qY7D591RCSFhMULyzL9CuyrGc+3PpB0h7dU4Qqw6GNyo4BNFjHZVvsWncrUlKX3DIKg0Y7rNNr06NQ==
|
||||
"@vue/runtime-core@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.5.tgz#2bf253a6f6b0430af1aacf0fdfd8f5782feefce9"
|
||||
integrity sha512-wh9ELIOQKeWT9SaUPdLrsxRkZv14jp+SJm9aiQGWio+/MWNM3Lib0wE6CoKEqQ9+SCYyGjDBhTOTtO47kCgbkg==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/reactivity" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
"@vue/runtime-dom@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.3.tgz#54a6115cfba364f20cdf5a44c2ff87337a57def8"
|
||||
integrity sha512-wrsprg7An5Ec+EhPngWdPuzkp0BEUxAKaQtN9dPU/iZctPyD9aaXmVtehPJerdQxQale6gEnhpnfywNw3zOv2A==
|
||||
"@vue/runtime-dom@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.5.tgz#b43736d66c32f6038778024587592cb9d68495de"
|
||||
integrity sha512-n5ewvOjyG3IEpqGBahdPXODFSpVlSz3H4LF76Sx0XAqpIOqyJ5bIb2PrdYuH2ogBMAQPh+o5tnoH4nJpBr8U0Q==
|
||||
dependencies:
|
||||
"@vue/runtime-core" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/runtime-core" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
csstype "^3.1.3"
|
||||
|
||||
"@vue/server-renderer@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.3.tgz#c508f58b9f83f0959085d5aa6854eac9141b4bc6"
|
||||
integrity sha512-BUxt8oVGMKKsqSkM1uU3d3Houyfy4WAc2SpSQRebNd+XJGATVkW/rO129jkyL+kpB/2VRKzE63zwf5RtJ3XuZw==
|
||||
"@vue/server-renderer@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.5.tgz#4bfa7aa763217d8b2d4767d2c8d968a9d40352c1"
|
||||
integrity sha512-jOFc/VE87yvifQpNju12VcqimH8pBLxdcT+t3xMeiED1K6DfH9SORyhFEoZlW5TG2Vwfn3Ul5KE+1aC99xnSBg==
|
||||
dependencies:
|
||||
"@vue/compiler-ssr" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/compiler-ssr" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
"@vue/shared@3.2.47":
|
||||
version "3.2.47"
|
||||
@ -733,10 +733,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.2.tgz#774cd9b4635ce801b70a3fc3713779a5ef5d77c3"
|
||||
integrity sha512-0rFu3h8JbclbnvvKrs7Fe5FNGV9/5X2rPD7KmOzhLSUAiQH5//Hq437Gv0fR5Mev3u/nbtvmLl8XgwCU20/ZfQ==
|
||||
|
||||
"@vue/shared@3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.3.tgz#01d54b32b9796c85c853c670d9395a813f23a8c2"
|
||||
integrity sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ==
|
||||
"@vue/shared@3.4.5":
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.5.tgz#c8b4eb6399a7fc986565ea736d938b3a1579256d"
|
||||
integrity sha512-6XptuzlMvN4l4cDnDw36pdGEV+9njYkQ1ZE0Q6iZLwrKefKaOJyiFmcP3/KBDHbt72cJZGtllAc1GaHe6XGAyg==
|
||||
|
||||
"@vue/tsconfig@^0.5.1":
|
||||
version "0.5.1"
|
||||
@ -2226,10 +2226,10 @@ safe-regex-test@^1.0.0:
|
||||
get-intrinsic "^1.1.3"
|
||||
is-regex "^1.1.4"
|
||||
|
||||
sass@^1.69.6:
|
||||
version "1.69.6"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.6.tgz#88ae1f93facc46d2da9b0bdd652d65068bcfa397"
|
||||
integrity sha512-qbRr3k9JGHWXCvZU77SD2OTwUlC+gNT+61JOLcmLm+XqH4h/5D+p4IIsxvpkB89S9AwJOyb5+rWNpIucaFxSFQ==
|
||||
sass@^1.69.7:
|
||||
version "1.69.7"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.7.tgz#6e7e1c8f51e8162faec3e9619babc7da780af3b7"
|
||||
integrity sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
@ -2666,16 +2666,16 @@ vue3-calendar-heatmap@^2.0.5:
|
||||
resolved "https://registry.yarnpkg.com/vue3-calendar-heatmap/-/vue3-calendar-heatmap-2.0.5.tgz#775a8d4e9d7bc62f242d7d6f28a899a3fae2bb82"
|
||||
integrity sha512-qvveNQlTS5Aw7AvRLs0zOyu3uP5iGJlXJAnkrkG2ElDdyQ8H1TJhQ8rL702CROjAg16ezIveUY10nCO7lqZ25w==
|
||||
|
||||
vue@^3.4.3:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.3.tgz#e1ba36a64134dcedc12cfb2c28e7cd15ba121f04"
|
||||
integrity sha512-GjN+culMAGv/mUbkIv8zMKItno8npcj5gWlXkSxf1SPTQf8eJ4A+YfHIvQFyL1IfuJcMl3soA7SmN1fRxbf/wA==
|
||||
vue@^3.4.5:
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.5.tgz#c08b9d903a20faaf4df7270bf2fa7487741b2294"
|
||||
integrity sha512-VH6nHFhLPjgu2oh5vEBXoNZxsGHuZNr3qf4PHClwJWw6IDqw6B3x+4J+ABdoZ0aJuT8Zi0zf3GpGlLQCrGWHrw==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.4.3"
|
||||
"@vue/compiler-sfc" "3.4.3"
|
||||
"@vue/runtime-dom" "3.4.3"
|
||||
"@vue/server-renderer" "3.4.3"
|
||||
"@vue/shared" "3.4.3"
|
||||
"@vue/compiler-dom" "3.4.5"
|
||||
"@vue/compiler-sfc" "3.4.5"
|
||||
"@vue/runtime-dom" "3.4.5"
|
||||
"@vue/server-renderer" "3.4.5"
|
||||
"@vue/shared" "3.4.5"
|
||||
|
||||
webpack-sources@^3.2.3:
|
||||
version "3.2.3"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user