Merge remote-tracking branch 'tbnobody/OpenDTU/master' into development
This commit is contained in:
commit
ebacc2f25f
47
docs/DeviceProfiles/olimex_esp32_gateway.json
Normal file
47
docs/DeviceProfiles/olimex_esp32_gateway.json
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Olimex ESP32-Gateway",
|
||||||
|
"nrf24": {
|
||||||
|
"miso": 14,
|
||||||
|
"mosi": 13,
|
||||||
|
"clk": 12,
|
||||||
|
"irq": 15,
|
||||||
|
"en": 2,
|
||||||
|
"cs": 4
|
||||||
|
},
|
||||||
|
"eth": {
|
||||||
|
"enabled": true,
|
||||||
|
"phy_addr": 0,
|
||||||
|
"power": 12,
|
||||||
|
"mdc": 23,
|
||||||
|
"mdio": 18,
|
||||||
|
"type": 0,
|
||||||
|
"clk_mode": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Olimex ESP32-Gateway with SSH1106",
|
||||||
|
"nrf24": {
|
||||||
|
"miso": 14,
|
||||||
|
"mosi": 13,
|
||||||
|
"clk": 12,
|
||||||
|
"irq": 15,
|
||||||
|
"en": 2,
|
||||||
|
"cs": 4
|
||||||
|
},
|
||||||
|
"eth": {
|
||||||
|
"enabled": true,
|
||||||
|
"phy_addr": 0,
|
||||||
|
"power": 12,
|
||||||
|
"mdc": 23,
|
||||||
|
"mdio": 18,
|
||||||
|
"type": 0,
|
||||||
|
"clk_mode": 3
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"type": 3,
|
||||||
|
"data": 32,
|
||||||
|
"clk": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
class DatastoreClass {
|
class DatastoreClass {
|
||||||
public:
|
public:
|
||||||
|
DatastoreClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
|
||||||
// Sum of yield total of all enabled inverters, a inverter which is just disabled at night is also included
|
// Sum of yield total of all enabled inverters, a inverter which is just disabled at night is also included
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
class InverterSettingsClass {
|
class InverterSettingsClass {
|
||||||
public:
|
public:
|
||||||
|
InverterSettingsClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
class MessageOutputClass : public Print {
|
class MessageOutputClass : public Print {
|
||||||
public:
|
public:
|
||||||
|
MessageOutputClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
size_t write(uint8_t c) override;
|
size_t write(uint8_t c) override;
|
||||||
size_t write(const uint8_t* buffer, size_t size) override;
|
size_t write(const uint8_t* buffer, size_t size) override;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
class MqttHandleDtuClass {
|
class MqttHandleDtuClass {
|
||||||
public:
|
public:
|
||||||
|
MqttHandleDtuClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -51,6 +51,7 @@ const byteAssign_fieldDeviceClass_t deviceFieldAssignment[] = {
|
|||||||
|
|
||||||
class MqttHandleHassClass {
|
class MqttHandleHassClass {
|
||||||
public:
|
public:
|
||||||
|
MqttHandleHassClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
void publishConfig();
|
void publishConfig();
|
||||||
void forceUpdate();
|
void forceUpdate();
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
class MqttHandleInverterClass {
|
class MqttHandleInverterClass {
|
||||||
public:
|
public:
|
||||||
|
MqttHandleInverterClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
class MqttHandleInverterTotalClass {
|
class MqttHandleInverterTotalClass {
|
||||||
public:
|
public:
|
||||||
|
MqttHandleInverterTotalClass();
|
||||||
void init(Scheduler& scheduler);
|
void init(Scheduler& scheduler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -46,10 +46,6 @@ public:
|
|||||||
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
|
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loop();
|
|
||||||
|
|
||||||
Task _loopTask;
|
|
||||||
|
|
||||||
AsyncWebServer _server;
|
AsyncWebServer _server;
|
||||||
|
|
||||||
WebApiBatteryClass _webApiBattery;
|
WebApiBatteryClass _webApiBattery;
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
class WebApiHuaweiClass {
|
class WebApiHuaweiClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
void getJsonData(JsonVariant& root);
|
void getJsonData(JsonVariant& root);
|
||||||
private:
|
private:
|
||||||
void onStatus(AsyncWebServerRequest* request);
|
void onStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,12 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiBatteryClass {
|
class WebApiBatteryClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onStatus(AsyncWebServerRequest* request);
|
void onStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiConfigClass {
|
class WebApiConfigClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onConfigGet(AsyncWebServerRequest* request);
|
void onConfigGet(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiDeviceClass {
|
class WebApiDeviceClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDeviceAdminGet(AsyncWebServerRequest* request);
|
void onDeviceAdminGet(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiDevInfoClass {
|
class WebApiDevInfoClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDevInfoStatus(AsyncWebServerRequest* request);
|
void onDevInfoStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,16 +2,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiDtuClass {
|
class WebApiDtuClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
WebApiDtuClass();
|
||||||
void loop();
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDtuAdminGet(AsyncWebServerRequest* request);
|
void onDtuAdminGet(AsyncWebServerRequest* request);
|
||||||
void onDtuAdminPost(AsyncWebServerRequest* request);
|
void onDtuAdminPost(AsyncWebServerRequest* request);
|
||||||
|
|
||||||
AsyncWebServer* _server;
|
AsyncWebServer* _server;
|
||||||
bool _performReload = false;
|
|
||||||
|
Task _applyDataTask;
|
||||||
|
void applyDataTaskCb();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiEventlogClass {
|
class WebApiEventlogClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEventlogStatus(AsyncWebServerRequest* request);
|
void onEventlogStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiFirmwareClass {
|
class WebApiFirmwareClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onFirmwareUpdateFinish(AsyncWebServerRequest* request);
|
void onFirmwareUpdateFinish(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiGridProfileClass {
|
class WebApiGridProfileClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onGridProfileStatus(AsyncWebServerRequest* request);
|
void onGridProfileStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiInverterClass {
|
class WebApiInverterClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onInverterList(AsyncWebServerRequest* request);
|
void onInverterList(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiLimitClass {
|
class WebApiLimitClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onLimitStatus(AsyncWebServerRequest* request);
|
void onLimitStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiMaintenanceClass {
|
class WebApiMaintenanceClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onRebootPost(AsyncWebServerRequest* request);
|
void onRebootPost(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,13 +2,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
#define MQTT_JSON_DOC_SIZE 10240
|
#define MQTT_JSON_DOC_SIZE 10240
|
||||||
|
|
||||||
class WebApiMqttClass {
|
class WebApiMqttClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onMqttStatus(AsyncWebServerRequest* request);
|
void onMqttStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiNetworkClass {
|
class WebApiNetworkClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onNetworkStatus(AsyncWebServerRequest* request);
|
void onNetworkStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiNtpClass {
|
class WebApiNtpClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onNtpStatus(AsyncWebServerRequest* request);
|
void onNtpStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiPowerClass {
|
class WebApiPowerClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onPowerStatus(AsyncWebServerRequest* request);
|
void onPowerStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
|
|
||||||
class WebApiPowerLimiterClass {
|
class WebApiPowerLimiterClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onStatus(AsyncWebServerRequest* request);
|
void onStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
|
|
||||||
class WebApiPowerMeterClass {
|
class WebApiPowerMeterClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onStatus(AsyncWebServerRequest* request);
|
void onStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class WebApiPrometheusClass {
|
class WebApiPrometheusClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onPrometheusMetricsGet(AsyncWebServerRequest* request);
|
void onPrometheusMetricsGet(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiSecurityClass {
|
class WebApiSecurityClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onSecurityGet(AsyncWebServerRequest* request);
|
void onSecurityGet(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiSysstatusClass {
|
class WebApiSysstatusClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onSystemStatus(AsyncWebServerRequest* request);
|
void onSystemStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
|
|
||||||
class WebApiVedirectClass {
|
class WebApiVedirectClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onVedirectStatus(AsyncWebServerRequest* request);
|
void onVedirectStatus(AsyncWebServerRequest* request);
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiWebappClass {
|
class WebApiWebappClass {
|
||||||
public:
|
public:
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AsyncWebServer* _server;
|
AsyncWebServer* _server;
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsHuaweiLiveClass {
|
class WebApiWsHuaweiLiveClass {
|
||||||
public:
|
public:
|
||||||
WebApiWsHuaweiLiveClass();
|
WebApiWsHuaweiLiveClass();
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateJsonResponse(JsonVariant& root);
|
void generateJsonResponse(JsonVariant& root);
|
||||||
@ -19,8 +19,11 @@ private:
|
|||||||
AsyncWebServer* _server;
|
AsyncWebServer* _server;
|
||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
|
||||||
uint32_t _lastWsCleanup = 0;
|
|
||||||
uint32_t _lastUpdateCheck = 0;
|
|
||||||
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
|
Task _wsCleanupTask;
|
||||||
|
void wsCleanupTaskCb();
|
||||||
|
|
||||||
|
Task _sendDataTask;
|
||||||
|
void sendDataTaskCb();
|
||||||
};
|
};
|
||||||
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsBatteryLiveClass {
|
class WebApiWsBatteryLiveClass {
|
||||||
public:
|
public:
|
||||||
WebApiWsBatteryLiveClass();
|
WebApiWsBatteryLiveClass();
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateJsonResponse(JsonVariant& root);
|
void generateJsonResponse(JsonVariant& root);
|
||||||
@ -19,9 +19,14 @@ private:
|
|||||||
AsyncWebServer* _server;
|
AsyncWebServer* _server;
|
||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
|
||||||
uint32_t _lastWsCleanup = 0;
|
|
||||||
uint32_t _lastUpdateCheck = 0;
|
uint32_t _lastUpdateCheck = 0;
|
||||||
static constexpr uint16_t _responseSize = 1024 + 512;
|
static constexpr uint16_t _responseSize = 1024 + 512;
|
||||||
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
|
Task _wsCleanupTask;
|
||||||
|
void wsCleanupTaskCb();
|
||||||
|
|
||||||
|
Task _sendDataTask;
|
||||||
|
void sendDataTaskCb();
|
||||||
};
|
};
|
||||||
@ -2,16 +2,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiWsConsoleClass {
|
class WebApiWsConsoleClass {
|
||||||
public:
|
public:
|
||||||
WebApiWsConsoleClass();
|
WebApiWsConsoleClass();
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AsyncWebServer* _server;
|
AsyncWebServer* _server;
|
||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
|
||||||
uint32_t _lastWsCleanup = 0;
|
Task _wsCleanupTask;
|
||||||
|
void wsCleanupTaskCb();
|
||||||
};
|
};
|
||||||
@ -4,16 +4,16 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
|
||||||
class WebApiWsLiveClass {
|
class WebApiWsLiveClass {
|
||||||
public:
|
public:
|
||||||
WebApiWsLiveClass();
|
WebApiWsLiveClass();
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateJsonResponse(JsonVariant& root);
|
void generateJsonResponse(JsonVariant& root);
|
||||||
void addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic = "");
|
void addField(JsonObject& root, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic = "");
|
||||||
void addTotalField(JsonObject& root, const String& name, const float value, const String& unit, const uint8_t digits);
|
void addTotalField(JsonObject& root, const String& name, const float value, const String& unit, const uint8_t digits);
|
||||||
void onLivedataStatus(AsyncWebServerRequest* request);
|
void onLivedataStatus(AsyncWebServerRequest* request);
|
||||||
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||||
@ -22,9 +22,13 @@ private:
|
|||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
|
||||||
uint32_t _lastWsPublish = 0;
|
uint32_t _lastWsPublish = 0;
|
||||||
uint32_t _lastInvUpdateCheck = 0;
|
|
||||||
uint32_t _lastWsCleanup = 0;
|
|
||||||
uint32_t _newestInverterTimestamp = 0;
|
uint32_t _newestInverterTimestamp = 0;
|
||||||
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
|
Task _wsCleanupTask;
|
||||||
|
void wsCleanupTaskCb();
|
||||||
|
|
||||||
|
Task _sendDataTask;
|
||||||
|
void sendDataTaskCb();
|
||||||
};
|
};
|
||||||
@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
#include <VeDirectMpptController.h>
|
#include <VeDirectMpptController.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsVedirectLiveClass {
|
class WebApiWsVedirectLiveClass {
|
||||||
public:
|
public:
|
||||||
WebApiWsVedirectLiveClass();
|
WebApiWsVedirectLiveClass();
|
||||||
void init(AsyncWebServer& server);
|
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||||
void loop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateJsonResponse(JsonVariant& root);
|
void generateJsonResponse(JsonVariant& root);
|
||||||
@ -21,9 +21,14 @@ private:
|
|||||||
AsyncWebSocket _ws;
|
AsyncWebSocket _ws;
|
||||||
|
|
||||||
uint32_t _lastWsPublish = 0;
|
uint32_t _lastWsPublish = 0;
|
||||||
uint32_t _lastWsCleanup = 0;
|
|
||||||
uint32_t _dataAgeMillis = 0;
|
uint32_t _dataAgeMillis = 0;
|
||||||
static constexpr uint16_t _responseSize = 1024 + 128;
|
static constexpr uint16_t _responseSize = 1024 + 128;
|
||||||
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
|
Task _wsCleanupTask;
|
||||||
|
void wsCleanupTaskCb();
|
||||||
|
|
||||||
|
Task _sendDataTask;
|
||||||
|
void sendDataTaskCb();
|
||||||
};
|
};
|
||||||
@ -137,6 +137,14 @@ time_t DevInfoParser::getFwBuildDateTime() const
|
|||||||
return timegm(&timeinfo);
|
return timegm(&timeinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String DevInfoParser::getFwBuildDateTimeStr() const
|
||||||
|
{
|
||||||
|
char timebuffer[32];
|
||||||
|
const time_t t = getFwBuildDateTime();
|
||||||
|
std::strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", gmtime(&t));
|
||||||
|
return timebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t DevInfoParser::getFwBootloaderVersion() const
|
uint16_t DevInfoParser::getFwBootloaderVersion() const
|
||||||
{
|
{
|
||||||
HOY_SEMAPHORE_TAKE();
|
HOY_SEMAPHORE_TAKE();
|
||||||
|
|||||||
@ -21,6 +21,7 @@ public:
|
|||||||
|
|
||||||
uint16_t getFwBuildVersion() const;
|
uint16_t getFwBuildVersion() const;
|
||||||
time_t getFwBuildDateTime() const;
|
time_t getFwBuildDateTime() const;
|
||||||
|
String getFwBuildDateTimeStr() const;
|
||||||
uint16_t getFwBootloaderVersion() const;
|
uint16_t getFwBootloaderVersion() const;
|
||||||
|
|
||||||
uint32_t getHwPartNumber() const;
|
uint32_t getHwPartNumber() const;
|
||||||
|
|||||||
@ -390,7 +390,7 @@ std::vector<uint8_t> GridProfileParser::getRawData() const
|
|||||||
{
|
{
|
||||||
std::vector<uint8_t> ret;
|
std::vector<uint8_t> ret;
|
||||||
HOY_SEMAPHORE_TAKE();
|
HOY_SEMAPHORE_TAKE();
|
||||||
for (uint8_t i = 0; i < GRID_PROFILE_SIZE; i++) {
|
for (uint8_t i = 0; i < _gridProfileLength; i++) {
|
||||||
ret.push_back(_payloadGridProfile[i]);
|
ret.push_back(_payloadGridProfile[i]);
|
||||||
}
|
}
|
||||||
HOY_SEMAPHORE_GIVE();
|
HOY_SEMAPHORE_GIVE();
|
||||||
|
|||||||
@ -37,13 +37,12 @@ build_unflags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||||
bblanchon/ArduinoJson @ ^6.21.4
|
bblanchon/ArduinoJson @ ^6.21.5
|
||||||
https://github.com/bertmelis/espMqttClient.git#v1.5.0
|
https://github.com/bertmelis/espMqttClient.git#v1.5.0
|
||||||
nrf24/RF24 @ ^1.4.8
|
nrf24/RF24 @ ^1.4.8
|
||||||
olikraus/U8g2 @ ^2.35.9
|
olikraus/U8g2 @ ^2.35.9
|
||||||
buelowp/sunset @ ^1.1.7
|
buelowp/sunset @ ^1.1.7
|
||||||
https://github.com/arkhipenko/TaskScheduler#testing
|
https://github.com/arkhipenko/TaskScheduler#testing
|
||||||
https://github.com/arkhipenko/TaskScheduler#testing
|
|
||||||
https://github.com/coryjfowler/MCP_CAN_lib
|
https://github.com/coryjfowler/MCP_CAN_lib
|
||||||
plerup/EspSoftwareSerial @ ^8.0.1
|
plerup/EspSoftwareSerial @ ^8.0.1
|
||||||
https://github.com/dok-net/ghostl @ ^1.0.1
|
https://github.com/dok-net/ghostl @ ^1.0.1
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Thomas Basler and others
|
* Copyright (C) 2023-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "Datastore.h"
|
#include "Datastore.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
DatastoreClass Datastore;
|
DatastoreClass Datastore;
|
||||||
|
|
||||||
|
DatastoreClass::DatastoreClass()
|
||||||
|
: _loopTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&DatastoreClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void DatastoreClass::init(Scheduler& scheduler)
|
void DatastoreClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&DatastoreClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(1 * TASK_SECOND);
|
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ static const char* const i18n_yield_total_kwh[] = { "total: %.1f kWh", "Ges.: %.
|
|||||||
static const char* const i18n_date_format[] = { "%m/%d/%Y %H:%M", "%d.%m.%Y %H:%M", "%d/%m/%Y %H:%M" };
|
static const char* const i18n_date_format[] = { "%m/%d/%Y %H:%M", "%d.%m.%Y %H:%M", "%d/%m/%Y %H:%M" };
|
||||||
|
|
||||||
DisplayGraphicClass::DisplayGraphicClass()
|
DisplayGraphicClass::DisplayGraphicClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&DisplayGraphicClass::loop, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +56,6 @@ void DisplayGraphicClass::init(Scheduler& scheduler, const DisplayType_t type, c
|
|||||||
_diagram.init(scheduler, _display);
|
_diagram.init(scheduler, _display);
|
||||||
|
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&DisplayGraphicClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(_period);
|
_loopTask.setInterval(_period);
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
DisplayGraphicDiagramClass::DisplayGraphicDiagramClass()
|
DisplayGraphicDiagramClass::DisplayGraphicDiagramClass()
|
||||||
|
: _averageTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&DisplayGraphicDiagramClass::averageLoop, this))
|
||||||
|
, _dataPointTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&DisplayGraphicDiagramClass::dataPointLoop, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,14 +18,9 @@ void DisplayGraphicDiagramClass::init(Scheduler& scheduler, U8G2* display)
|
|||||||
_display = display;
|
_display = display;
|
||||||
|
|
||||||
scheduler.addTask(_averageTask);
|
scheduler.addTask(_averageTask);
|
||||||
_averageTask.setCallback(std::bind(&DisplayGraphicDiagramClass::averageLoop, this));
|
|
||||||
_averageTask.setIterations(TASK_FOREVER);
|
|
||||||
_averageTask.setInterval(1 * TASK_SECOND);
|
|
||||||
_averageTask.enable();
|
_averageTask.enable();
|
||||||
|
|
||||||
scheduler.addTask(_dataPointTask);
|
scheduler.addTask(_dataPointTask);
|
||||||
_dataPointTask.setCallback(std::bind(&DisplayGraphicDiagramClass::dataPointLoop, this));
|
|
||||||
_dataPointTask.setIterations(TASK_FOREVER);
|
|
||||||
updatePeriod();
|
updatePeriod();
|
||||||
_dataPointTask.enable();
|
_dataPointTask.enable();
|
||||||
}
|
}
|
||||||
@ -110,7 +107,9 @@ void DisplayGraphicDiagramClass::redraw(uint8_t screenSaverOffsetX, uint8_t xPos
|
|||||||
|
|
||||||
if (maxWatts > 0 && isFullscreen) {
|
if (maxWatts > 0 && isFullscreen) {
|
||||||
// draw y axis ticks
|
// draw y axis ticks
|
||||||
const uint16_t yAxisWattPerTick = maxWatts <= 100 ? 10 : maxWatts <= 1000 ? 100 : maxWatts < 5000 ? 500 : 1000;
|
const uint16_t yAxisWattPerTick = maxWatts <= 100 ? 10 : maxWatts <= 1000 ? 100
|
||||||
|
: maxWatts < 5000 ? 500
|
||||||
|
: 1000;
|
||||||
const uint8_t yAxisTickSizePixel = height / (maxWatts / yAxisWattPerTick);
|
const uint8_t yAxisTickSizePixel = height / (maxWatts / yAxisWattPerTick);
|
||||||
|
|
||||||
for (int16_t tickYPos = graphPosY + height; tickYPos > graphPosY - arrow_size; tickYPos -= yAxisTickSizePixel) {
|
for (int16_t tickYPos = graphPosY + height; tickYPos > graphPosY - arrow_size; tickYPos -= yAxisTickSizePixel) {
|
||||||
|
|||||||
@ -25,6 +25,12 @@
|
|||||||
|
|
||||||
InverterSettingsClass InverterSettings;
|
InverterSettingsClass InverterSettings;
|
||||||
|
|
||||||
|
InverterSettingsClass::InverterSettingsClass()
|
||||||
|
: _settingsTask(INVERTER_UPDATE_SETTINGS_INTERVAL, TASK_FOREVER, std::bind(&InverterSettingsClass::settingsLoop, this))
|
||||||
|
, _hoyTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&InverterSettingsClass::hoyLoop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void InverterSettingsClass::init(Scheduler& scheduler)
|
void InverterSettingsClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
const CONFIG_T& config = Configuration.get();
|
const CONFIG_T& config = Configuration.get();
|
||||||
@ -94,14 +100,9 @@ void InverterSettingsClass::init(Scheduler& scheduler)
|
|||||||
}
|
}
|
||||||
|
|
||||||
scheduler.addTask(_hoyTask);
|
scheduler.addTask(_hoyTask);
|
||||||
_hoyTask.setCallback(std::bind(&InverterSettingsClass::hoyLoop, this));
|
|
||||||
_hoyTask.setIterations(TASK_FOREVER);
|
|
||||||
_hoyTask.enable();
|
_hoyTask.enable();
|
||||||
|
|
||||||
scheduler.addTask(_settingsTask);
|
scheduler.addTask(_settingsTask);
|
||||||
_settingsTask.setCallback(std::bind(&InverterSettingsClass::settingsLoop, this));
|
|
||||||
_settingsTask.setIterations(TASK_FOREVER);
|
|
||||||
_settingsTask.setInterval(INVERTER_UPDATE_SETTINGS_INTERVAL);
|
|
||||||
_settingsTask.enable();
|
_settingsTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Thomas Basler and others
|
* Copyright (C) 2023-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "Led_Single.h"
|
#include "Led_Single.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -38,6 +38,8 @@ const uint8_t pwmTable[] = {
|
|||||||
#define LED_OFF 0
|
#define LED_OFF 0
|
||||||
|
|
||||||
LedSingleClass::LedSingleClass()
|
LedSingleClass::LedSingleClass()
|
||||||
|
: _setTask(LEDSINGLE_UPDATE_INTERVAL * TASK_MILLISECOND, TASK_FOREVER, std::bind(&LedSingleClass::setLoop, this))
|
||||||
|
, _outputTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&LedSingleClass::outputLoop, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +64,9 @@ void LedSingleClass::init(Scheduler& scheduler)
|
|||||||
|
|
||||||
if (ledActive) {
|
if (ledActive) {
|
||||||
scheduler.addTask(_outputTask);
|
scheduler.addTask(_outputTask);
|
||||||
_outputTask.setCallback(std::bind(&LedSingleClass::outputLoop, this));
|
|
||||||
_outputTask.setIterations(TASK_FOREVER);
|
|
||||||
_outputTask.enable();
|
_outputTask.enable();
|
||||||
|
|
||||||
scheduler.addTask(_setTask);
|
scheduler.addTask(_setTask);
|
||||||
_setTask.setCallback(std::bind(&LedSingleClass::setLoop, this));
|
|
||||||
_setTask.setInterval(LEDSINGLE_UPDATE_INTERVAL * TASK_MILLISECOND);
|
|
||||||
_setTask.setIterations(TASK_FOREVER);
|
|
||||||
_setTask.enable();
|
_setTask.enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
// 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 <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
|
||||||
MessageOutputClass MessageOutput;
|
MessageOutputClass MessageOutput;
|
||||||
|
|
||||||
|
MessageOutputClass::MessageOutputClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&MessageOutputClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MessageOutputClass::init(Scheduler& scheduler)
|
void MessageOutputClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&MessageOutputClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "MqttHandleDtu.h"
|
#include "MqttHandleDtu.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
MqttHandleDtuClass MqttHandleDtu;
|
MqttHandleDtuClass MqttHandleDtu;
|
||||||
|
|
||||||
|
MqttHandleDtuClass::MqttHandleDtuClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&MqttHandleDtuClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MqttHandleDtuClass::init(Scheduler& scheduler)
|
void MqttHandleDtuClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&MqttHandleDtuClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "MqttHandleHass.h"
|
#include "MqttHandleHass.h"
|
||||||
#include "MqttHandleInverter.h"
|
#include "MqttHandleInverter.h"
|
||||||
@ -11,11 +11,14 @@
|
|||||||
|
|
||||||
MqttHandleHassClass MqttHandleHass;
|
MqttHandleHassClass MqttHandleHass;
|
||||||
|
|
||||||
|
MqttHandleHassClass::MqttHandleHassClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&MqttHandleHassClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MqttHandleHassClass::init(Scheduler& scheduler)
|
void MqttHandleHassClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&MqttHandleHassClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,5 +424,5 @@ void MqttHandleHassClass::publish(const String& subtopic, const String& payload)
|
|||||||
{
|
{
|
||||||
String topic = Configuration.get().Mqtt.Hass.Topic;
|
String topic = Configuration.get().Mqtt.Hass.Topic;
|
||||||
topic += subtopic;
|
topic += subtopic;
|
||||||
MqttSettings.publishGeneric(topic.c_str(), payload.c_str(), Configuration.get().Mqtt.Hass.Retain);
|
MqttSettings.publishGeneric(topic, payload, Configuration.get().Mqtt.Hass.Retain);
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "MqttHandleInverter.h"
|
#include "MqttHandleInverter.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
@ -18,6 +18,11 @@
|
|||||||
|
|
||||||
MqttHandleInverterClass MqttHandleInverter;
|
MqttHandleInverterClass MqttHandleInverter;
|
||||||
|
|
||||||
|
MqttHandleInverterClass::MqttHandleInverterClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&MqttHandleInverterClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MqttHandleInverterClass::init(Scheduler& scheduler)
|
void MqttHandleInverterClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
@ -28,16 +33,14 @@ void MqttHandleInverterClass::init(Scheduler& scheduler)
|
|||||||
using std::placeholders::_6;
|
using std::placeholders::_6;
|
||||||
|
|
||||||
const String topic = MqttSettings.getPrefix();
|
const String topic = MqttSettings.getPrefix();
|
||||||
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_PERSISTENT_RELATIVE).c_str(), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
|
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).c_str(), 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).c_str(), 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).c_str(), 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).c_str(), 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).c_str(), 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.setCallback(std::bind(&MqttHandleInverterClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
@ -68,10 +71,7 @@ void MqttHandleInverterClass::loop()
|
|||||||
MqttSettings.publish(subtopic + "/device/fwbuildversion", String(inv->DevInfo()->getFwBuildVersion()));
|
MqttSettings.publish(subtopic + "/device/fwbuildversion", String(inv->DevInfo()->getFwBuildVersion()));
|
||||||
|
|
||||||
// Firmware Build DateTime
|
// Firmware Build DateTime
|
||||||
char timebuffer[32];
|
MqttSettings.publish(subtopic + "/device/fwbuilddatetime", inv->DevInfo()->getFwBuildDateTimeStr());
|
||||||
const time_t t = inv->DevInfo()->getFwBuildDateTime();
|
|
||||||
std::strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", gmtime(&t));
|
|
||||||
MqttSettings.publish(subtopic + "/device/fwbuilddatetime", String(timebuffer));
|
|
||||||
|
|
||||||
// Hardware part number
|
// Hardware part number
|
||||||
MqttSettings.publish(subtopic + "/device/hwpartnumber", String(inv->DevInfo()->getHwPartNumber()));
|
MqttSettings.publish(subtopic + "/device/hwpartnumber", String(inv->DevInfo()->getHwPartNumber()));
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Thomas Basler and others
|
* Copyright (C) 2023-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "MqttHandleInverterTotal.h"
|
#include "MqttHandleInverterTotal.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
MqttHandleInverterTotalClass MqttHandleInverterTotal;
|
MqttHandleInverterTotalClass MqttHandleInverterTotal;
|
||||||
|
|
||||||
|
MqttHandleInverterTotalClass::MqttHandleInverterTotalClass()
|
||||||
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&MqttHandleInverterTotalClass::loop, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MqttHandleInverterTotalClass::init(Scheduler& scheduler)
|
void MqttHandleInverterTotalClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&MqttHandleInverterTotalClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
_loopTask.setInterval(Configuration.get().Mqtt.PublishInterval * TASK_SECOND);
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "NetworkSettings.h"
|
#include "NetworkSettings.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -12,7 +12,8 @@
|
|||||||
#include <ETH.h>
|
#include <ETH.h>
|
||||||
|
|
||||||
NetworkSettingsClass::NetworkSettingsClass()
|
NetworkSettingsClass::NetworkSettingsClass()
|
||||||
: _apIp(192, 168, 4, 1)
|
: _loopTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&NetworkSettingsClass::loop, this))
|
||||||
|
, _apIp(192, 168, 4, 1)
|
||||||
, _apNetmask(255, 255, 255, 0)
|
, _apNetmask(255, 255, 255, 0)
|
||||||
{
|
{
|
||||||
_dnsServer.reset(new DNSServer());
|
_dnsServer.reset(new DNSServer());
|
||||||
@ -29,8 +30,6 @@ void NetworkSettingsClass::init(Scheduler& scheduler)
|
|||||||
setupMode();
|
setupMode();
|
||||||
|
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&NetworkSettingsClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Thomas Basler and others
|
* Copyright (C) 2023-2024 Thomas Basler and others
|
||||||
*/
|
*/
|
||||||
#include "SunPosition.h"
|
#include "SunPosition.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,15 +10,13 @@
|
|||||||
SunPositionClass SunPosition;
|
SunPositionClass SunPosition;
|
||||||
|
|
||||||
SunPositionClass::SunPositionClass()
|
SunPositionClass::SunPositionClass()
|
||||||
|
: _loopTask(5 * TASK_SECOND, TASK_FOREVER, std::bind(&SunPositionClass::loop, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunPositionClass::init(Scheduler& scheduler)
|
void SunPositionClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
scheduler.addTask(_loopTask);
|
scheduler.addTask(_loopTask);
|
||||||
_loopTask.setCallback(std::bind(&SunPositionClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.setInterval(5 * TASK_SECOND);
|
|
||||||
_loopTask.enable();
|
_loopTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -14,72 +14,36 @@ WebApiClass::WebApiClass()
|
|||||||
|
|
||||||
void WebApiClass::init(Scheduler& scheduler)
|
void WebApiClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
_webApiConfig.init(_server);
|
_webApiConfig.init(_server, scheduler);
|
||||||
_webApiDevice.init(_server);
|
_webApiDevice.init(_server, scheduler);
|
||||||
_webApiDevInfo.init(_server);
|
_webApiDevInfo.init(_server, scheduler);
|
||||||
_webApiDtu.init(_server);
|
_webApiDtu.init(_server, scheduler);
|
||||||
_webApiEventlog.init(_server);
|
_webApiEventlog.init(_server, scheduler);
|
||||||
_webApiFirmware.init(_server);
|
_webApiFirmware.init(_server, scheduler);
|
||||||
_webApiGridprofile.init(_server);
|
_webApiGridprofile.init(_server, scheduler);
|
||||||
_webApiInverter.init(_server);
|
_webApiInverter.init(_server, scheduler);
|
||||||
_webApiLimit.init(_server);
|
_webApiLimit.init(_server, scheduler);
|
||||||
_webApiMaintenance.init(_server);
|
_webApiMaintenance.init(_server, scheduler);
|
||||||
_webApiMqtt.init(_server);
|
_webApiMqtt.init(_server, scheduler);
|
||||||
_webApiNetwork.init(_server);
|
_webApiNetwork.init(_server, scheduler);
|
||||||
_webApiNtp.init(_server);
|
_webApiNtp.init(_server, scheduler);
|
||||||
_webApiPower.init(_server);
|
_webApiPower.init(_server, scheduler);
|
||||||
_webApiPrometheus.init(_server);
|
_webApiPrometheus.init(_server, scheduler);
|
||||||
_webApiSecurity.init(_server);
|
_webApiSecurity.init(_server, scheduler);
|
||||||
_webApiSysstatus.init(_server);
|
_webApiSysstatus.init(_server, scheduler);
|
||||||
_webApiWebapp.init(_server);
|
_webApiWebapp.init(_server, scheduler);
|
||||||
_webApiWsConsole.init(_server);
|
_webApiWsConsole.init(_server, scheduler);
|
||||||
_webApiWsLive.init(_server);
|
_webApiWsLive.init(_server, scheduler);
|
||||||
_webApiBattery.init(_server);
|
_webApiBattery.init(_server, scheduler);
|
||||||
_webApiPowerMeter.init(_server);
|
_webApiPowerMeter.init(_server, scheduler);
|
||||||
_webApiPowerLimiter.init(_server);
|
_webApiPowerLimiter.init(_server, scheduler);
|
||||||
_webApiWsVedirectLive.init(_server);
|
_webApiWsVedirectLive.init(_server, scheduler);
|
||||||
_webApiVedirect.init(_server);
|
_webApiVedirect.init(_server, scheduler);
|
||||||
_webApiWsHuaweiLive.init(_server);
|
_webApiWsHuaweiLive.init(_server, scheduler);
|
||||||
_webApiHuaweiClass.init(_server);
|
_webApiHuaweiClass.init(_server, scheduler);
|
||||||
_webApiWsBatteryLive.init(_server);
|
_webApiWsBatteryLive.init(_server, scheduler);
|
||||||
|
|
||||||
_server.begin();
|
_server.begin();
|
||||||
|
|
||||||
scheduler.addTask(_loopTask);
|
|
||||||
_loopTask.setCallback(std::bind(&WebApiClass::loop, this));
|
|
||||||
_loopTask.setIterations(TASK_FOREVER);
|
|
||||||
_loopTask.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiClass::loop()
|
|
||||||
{
|
|
||||||
_webApiBattery.loop();
|
|
||||||
_webApiConfig.loop();
|
|
||||||
_webApiDevice.loop();
|
|
||||||
_webApiDevInfo.loop();
|
|
||||||
_webApiDtu.loop();
|
|
||||||
_webApiEventlog.loop();
|
|
||||||
_webApiFirmware.loop();
|
|
||||||
_webApiGridprofile.loop();
|
|
||||||
_webApiInverter.loop();
|
|
||||||
_webApiLimit.loop();
|
|
||||||
_webApiMaintenance.loop();
|
|
||||||
_webApiMqtt.loop();
|
|
||||||
_webApiNetwork.loop();
|
|
||||||
_webApiNtp.loop();
|
|
||||||
_webApiPower.loop();
|
|
||||||
_webApiPowerMeter.loop();
|
|
||||||
_webApiPowerLimiter.loop();
|
|
||||||
_webApiSecurity.loop();
|
|
||||||
_webApiSysstatus.loop();
|
|
||||||
_webApiWebapp.loop();
|
|
||||||
_webApiWsConsole.loop();
|
|
||||||
_webApiWsLive.loop();
|
|
||||||
_webApiWsVedirectLive.loop();
|
|
||||||
_webApiVedirect.loop();
|
|
||||||
_webApiWsHuaweiLive.loop();
|
|
||||||
_webApiHuaweiClass.loop();
|
|
||||||
_webApiWsBatteryLive.loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
||||||
|
|||||||
@ -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 "WebApi_Huawei.h"
|
#include "WebApi_Huawei.h"
|
||||||
#include "Huawei_can.h"
|
#include "Huawei_can.h"
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiHuaweiClass::init(AsyncWebServer& server)
|
void WebApiHuaweiClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -24,10 +24,6 @@ void WebApiHuaweiClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/huawei/limit/config", HTTP_POST, std::bind(&WebApiHuaweiClass::onPost, this, _1));
|
_server->on("/api/huawei/limit/config", HTTP_POST, std::bind(&WebApiHuaweiClass::onPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiHuaweiClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiHuaweiClass::getJsonData(JsonVariant& root) {
|
void WebApiHuaweiClass::getJsonData(JsonVariant& root) {
|
||||||
const RectifierParameters_t * rp = HuaweiCan.get();
|
const RectifierParameters_t * rp = HuaweiCan.get();
|
||||||
|
|
||||||
|
|||||||
@ -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 "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
|
||||||
void WebApiBatteryClass::init(AsyncWebServer& server)
|
void WebApiBatteryClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -24,10 +24,6 @@ void WebApiBatteryClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/battery/config", HTTP_POST, std::bind(&WebApiBatteryClass::onAdminPost, this, _1));
|
_server->on("/api/battery/config", HTTP_POST, std::bind(&WebApiBatteryClass::onAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiBatteryClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
|
void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_config.h"
|
#include "WebApi_config.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
|
||||||
void WebApiConfigClass::init(AsyncWebServer& server)
|
void WebApiConfigClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -29,10 +29,6 @@ void WebApiConfigClass::init(AsyncWebServer& server)
|
|||||||
std::bind(&WebApiConfigClass::onConfigUpload, this, _1, _2, _3, _4, _5, _6));
|
std::bind(&WebApiConfigClass::onConfigUpload, this, _1, _2, _3, _4, _5, _6));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiConfigClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiConfigClass::onConfigGet(AsyncWebServerRequest* request)
|
void WebApiConfigClass::onConfigGet(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_device.h"
|
#include "WebApi_device.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiDeviceClass::init(AsyncWebServer& server)
|
void WebApiDeviceClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -22,10 +22,6 @@ void WebApiDeviceClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/device/config", HTTP_POST, std::bind(&WebApiDeviceClass::onDeviceAdminPost, this, _1));
|
_server->on("/api/device/config", HTTP_POST, std::bind(&WebApiDeviceClass::onDeviceAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiDeviceClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_devinfo.h"
|
#include "WebApi_devinfo.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
void WebApiDevInfoClass::init(AsyncWebServer& server)
|
void WebApiDevInfoClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -17,10 +17,6 @@ void WebApiDevInfoClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/devinfo/status", HTTP_GET, std::bind(&WebApiDevInfoClass::onDevInfoStatus, this, _1));
|
_server->on("/api/devinfo/status", HTTP_GET, std::bind(&WebApiDevInfoClass::onDevInfoStatus, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiDevInfoClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request)
|
void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
@ -46,11 +42,7 @@ void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request)
|
|||||||
root["hw_version"] = inv->DevInfo()->getHwVersion();
|
root["hw_version"] = inv->DevInfo()->getHwVersion();
|
||||||
root["hw_model_name"] = inv->DevInfo()->getHwModelName();
|
root["hw_model_name"] = inv->DevInfo()->getHwModelName();
|
||||||
root["max_power"] = inv->DevInfo()->getMaxPower();
|
root["max_power"] = inv->DevInfo()->getMaxPower();
|
||||||
|
root["fw_build_datetime"] = inv->DevInfo()->getFwBuildDateTimeStr();
|
||||||
char timebuffer[32];
|
|
||||||
const time_t t = inv->DevInfo()->getFwBuildDateTime();
|
|
||||||
std::strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", gmtime(&t));
|
|
||||||
root["fw_build_datetime"] = String(timebuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
|
|||||||
@ -9,7 +9,12 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiDtuClass::init(AsyncWebServer& server)
|
WebApiDtuClass::WebApiDtuClass()
|
||||||
|
: _applyDataTask(TASK_IMMEDIATE, TASK_ONCE, std::bind(&WebApiDtuClass::applyDataTaskCb, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebApiDtuClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -17,11 +22,12 @@ void WebApiDtuClass::init(AsyncWebServer& server)
|
|||||||
|
|
||||||
_server->on("/api/dtu/config", HTTP_GET, std::bind(&WebApiDtuClass::onDtuAdminGet, this, _1));
|
_server->on("/api/dtu/config", HTTP_GET, std::bind(&WebApiDtuClass::onDtuAdminGet, this, _1));
|
||||||
_server->on("/api/dtu/config", HTTP_POST, std::bind(&WebApiDtuClass::onDtuAdminPost, this, _1));
|
_server->on("/api/dtu/config", HTTP_POST, std::bind(&WebApiDtuClass::onDtuAdminPost, this, _1));
|
||||||
|
|
||||||
|
scheduler.addTask(_applyDataTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiDtuClass::loop()
|
void WebApiDtuClass::applyDataTaskCb()
|
||||||
{
|
{
|
||||||
if (_performReload) {
|
|
||||||
// Execute stuff in main thread to avoid busy SPI bus
|
// Execute stuff in main thread to avoid busy SPI bus
|
||||||
CONFIG_T& config = Configuration.get();
|
CONFIG_T& config = Configuration.get();
|
||||||
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu.Nrf.PaLevel);
|
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu.Nrf.PaLevel);
|
||||||
@ -31,8 +37,6 @@ void WebApiDtuClass::loop()
|
|||||||
Hoymiles.getRadioCmt()->setCountryMode(static_cast<CountryModeId_t>(config.Dtu.Cmt.CountryMode));
|
Hoymiles.getRadioCmt()->setCountryMode(static_cast<CountryModeId_t>(config.Dtu.Cmt.CountryMode));
|
||||||
Hoymiles.getRadioCmt()->setInverterTargetFrequency(config.Dtu.Cmt.Frequency);
|
Hoymiles.getRadioCmt()->setInverterTargetFrequency(config.Dtu.Cmt.Frequency);
|
||||||
Hoymiles.setPollInterval(config.Dtu.PollInterval);
|
Hoymiles.setPollInterval(config.Dtu.PollInterval);
|
||||||
_performReload = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request)
|
void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request)
|
||||||
@ -199,5 +203,5 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
|||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
_performReload = true;
|
_applyDataTask.enable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
// 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 "WebApi_eventlog.h"
|
#include "WebApi_eventlog.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiEventlogClass::init(AsyncWebServer& server)
|
void WebApiEventlogClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -16,10 +16,6 @@ void WebApiEventlogClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/eventlog/status", HTTP_GET, std::bind(&WebApiEventlogClass::onEventlogStatus, this, _1));
|
_server->on("/api/eventlog/status", HTTP_GET, std::bind(&WebApiEventlogClass::onEventlogStatus, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiEventlogClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
|
void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_firmware.h"
|
#include "WebApi_firmware.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiFirmwareClass::init(AsyncWebServer& server)
|
void WebApiFirmwareClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -26,10 +26,6 @@ void WebApiFirmwareClass::init(AsyncWebServer& server)
|
|||||||
std::bind(&WebApiFirmwareClass::onFirmwareUpdateUpload, this, _1, _2, _3, _4, _5, _6));
|
std::bind(&WebApiFirmwareClass::onFirmwareUpdateUpload, this, _1, _2, _3, _4, _5, _6));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiFirmwareClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiFirmwareClass::onFirmwareUpdateFinish(AsyncWebServerRequest* request)
|
void WebApiFirmwareClass::onFirmwareUpdateFinish(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
// 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 "WebApi_gridprofile.h"
|
#include "WebApi_gridprofile.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiGridProfileClass::init(AsyncWebServer& server)
|
void WebApiGridProfileClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -17,10 +17,6 @@ void WebApiGridProfileClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/gridprofile/rawdata", HTTP_GET, std::bind(&WebApiGridProfileClass::onGridProfileRawdata, this, _1));
|
_server->on("/api/gridprofile/rawdata", HTTP_GET, std::bind(&WebApiGridProfileClass::onGridProfileRawdata, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiGridProfileClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
|
void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_inverter.h"
|
#include "WebApi_inverter.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiInverterClass::init(AsyncWebServer& server)
|
void WebApiInverterClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -25,10 +25,6 @@ void WebApiInverterClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/inverter/order", HTTP_POST, std::bind(&WebApiInverterClass::onInverterOrder, this, _1));
|
_server->on("/api/inverter/order", HTTP_POST, std::bind(&WebApiInverterClass::onInverterOrder, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiInverterClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
|
void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_limit.h"
|
#include "WebApi_limit.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiLimitClass::init(AsyncWebServer& server)
|
void WebApiLimitClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -20,10 +20,6 @@ void WebApiLimitClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/limit/config", HTTP_POST, std::bind(&WebApiLimitClass::onLimitPost, this, _1));
|
_server->on("/api/limit/config", HTTP_POST, std::bind(&WebApiLimitClass::onLimitPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiLimitClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request)
|
void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WebApi_maintenance.h"
|
#include "WebApi_maintenance.h"
|
||||||
@ -9,7 +9,7 @@
|
|||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiMaintenanceClass::init(AsyncWebServer& server)
|
void WebApiMaintenanceClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -18,10 +18,6 @@ void WebApiMaintenanceClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/maintenance/reboot", HTTP_POST, std::bind(&WebApiMaintenanceClass::onRebootPost, this, _1));
|
_server->on("/api/maintenance/reboot", HTTP_POST, std::bind(&WebApiMaintenanceClass::onRebootPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiMaintenanceClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request)
|
void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_mqtt.h"
|
#include "WebApi_mqtt.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -15,7 +15,7 @@
|
|||||||
#include "PowerMeter.h"
|
#include "PowerMeter.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiMqttClass::init(AsyncWebServer& server)
|
void WebApiMqttClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -26,10 +26,6 @@ void WebApiMqttClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/mqtt/config", HTTP_POST, std::bind(&WebApiMqttClass::onMqttAdminPost, this, _1));
|
_server->on("/api/mqtt/config", HTTP_POST, std::bind(&WebApiMqttClass::onMqttAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiMqttClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
|
void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_network.h"
|
#include "WebApi_network.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiNetworkClass::init(AsyncWebServer& server)
|
void WebApiNetworkClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -21,10 +21,6 @@ void WebApiNetworkClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/network/config", HTTP_POST, std::bind(&WebApiNetworkClass::onNetworkAdminPost, this, _1));
|
_server->on("/api/network/config", HTTP_POST, std::bind(&WebApiNetworkClass::onNetworkAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiNetworkClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiNetworkClass::onNetworkStatus(AsyncWebServerRequest* request)
|
void WebApiNetworkClass::onNetworkStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_ntp.h"
|
#include "WebApi_ntp.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiNtpClass::init(AsyncWebServer& server)
|
void WebApiNtpClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -24,10 +24,6 @@ void WebApiNtpClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/ntp/time", HTTP_POST, std::bind(&WebApiNtpClass::onNtpTimePost, this, _1));
|
_server->on("/api/ntp/time", HTTP_POST, std::bind(&WebApiNtpClass::onNtpTimePost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiNtpClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiNtpClass::onNtpStatus(AsyncWebServerRequest* request)
|
void WebApiNtpClass::onNtpStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_power.h"
|
#include "WebApi_power.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
|
|
||||||
void WebApiPowerClass::init(AsyncWebServer& server)
|
void WebApiPowerClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -18,10 +18,6 @@ void WebApiPowerClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/power/config", HTTP_POST, std::bind(&WebApiPowerClass::onPowerPost, this, _1));
|
_server->on("/api/power/config", HTTP_POST, std::bind(&WebApiPowerClass::onPowerPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiPowerClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request)
|
void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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 "WebApi_powerlimiter.h"
|
#include "WebApi_powerlimiter.h"
|
||||||
#include "VeDirectFrameHandler.h"
|
#include "VeDirectFrameHandler.h"
|
||||||
@ -16,7 +16,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
|
|
||||||
void WebApiPowerLimiterClass::init(AsyncWebServer& server)
|
void WebApiPowerLimiterClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -27,10 +27,6 @@ void WebApiPowerLimiterClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/powerlimiter/config", HTTP_POST, std::bind(&WebApiPowerLimiterClass::onAdminPost, this, _1));
|
_server->on("/api/powerlimiter/config", HTTP_POST, std::bind(&WebApiPowerLimiterClass::onAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiPowerLimiterClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiPowerLimiterClass::onStatus(AsyncWebServerRequest* request)
|
void WebApiPowerLimiterClass::onStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||||
|
|||||||
@ -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 "WebApi_powermeter.h"
|
#include "WebApi_powermeter.h"
|
||||||
#include "VeDirectFrameHandler.h"
|
#include "VeDirectFrameHandler.h"
|
||||||
@ -16,7 +16,7 @@
|
|||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
|
||||||
void WebApiPowerMeterClass::init(AsyncWebServer& server)
|
void WebApiPowerMeterClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -28,10 +28,6 @@ void WebApiPowerMeterClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/powermeter/testhttprequest", HTTP_POST, std::bind(&WebApiPowerMeterClass::onTestHttpRequest, this, _1));
|
_server->on("/api/powermeter/testhttprequest", HTTP_POST, std::bind(&WebApiPowerMeterClass::onTestHttpRequest, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiPowerMeterClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 2048);
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, 2048);
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_prometheus.h"
|
#include "WebApi_prometheus.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include <Hoymiles.h>
|
#include <Hoymiles.h>
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
|
||||||
void WebApiPrometheusClass::init(AsyncWebServer& server)
|
void WebApiPrometheusClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -20,10 +20,6 @@ void WebApiPrometheusClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/prometheus/metrics", HTTP_GET, std::bind(&WebApiPrometheusClass::onPrometheusMetricsGet, this, _1));
|
_server->on("/api/prometheus/metrics", HTTP_GET, std::bind(&WebApiPrometheusClass::onPrometheusMetricsGet, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiPrometheusClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiPrometheusClass::onPrometheusMetricsGet(AsyncWebServerRequest* request)
|
void WebApiPrometheusClass::onPrometheusMetricsGet(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_security.h"
|
#include "WebApi_security.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -9,7 +9,7 @@
|
|||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
void WebApiSecurityClass::init(AsyncWebServer& server)
|
void WebApiSecurityClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -20,10 +20,6 @@ void WebApiSecurityClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/security/authenticate", HTTP_GET, std::bind(&WebApiSecurityClass::onAuthenticateGet, this, _1));
|
_server->on("/api/security/authenticate", HTTP_GET, std::bind(&WebApiSecurityClass::onAuthenticateGet, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiSecurityClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiSecurityClass::onSecurityGet(AsyncWebServerRequest* request)
|
void WebApiSecurityClass::onSecurityGet(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_sysstatus.h"
|
#include "WebApi_sysstatus.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -20,7 +20,7 @@
|
|||||||
#define AUTO_GIT_BRANCH ""
|
#define AUTO_GIT_BRANCH ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void WebApiSysstatusClass::init(AsyncWebServer& server)
|
void WebApiSysstatusClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -29,10 +29,6 @@ void WebApiSysstatusClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/system/status", HTTP_GET, std::bind(&WebApiSysstatusClass::onSystemStatus, this, _1));
|
_server->on("/api/system/status", HTTP_GET, std::bind(&WebApiSysstatusClass::onSystemStatus, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiSysstatusClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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 "WebApi_vedirect.h"
|
#include "WebApi_vedirect.h"
|
||||||
#include "VictronMppt.h"
|
#include "VictronMppt.h"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include "WebApi_errors.h"
|
#include "WebApi_errors.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
|
||||||
void WebApiVedirectClass::init(AsyncWebServer& server)
|
void WebApiVedirectClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
@ -22,10 +22,6 @@ void WebApiVedirectClass::init(AsyncWebServer& server)
|
|||||||
_server->on("/api/vedirect/config", HTTP_POST, std::bind(&WebApiVedirectClass::onVedirectAdminPost, this, _1));
|
_server->on("/api/vedirect/config", HTTP_POST, std::bind(&WebApiVedirectClass::onVedirectAdminPost, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiVedirectClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebApiVedirectClass::onVedirectStatus(AsyncWebServerRequest* request)
|
void WebApiVedirectClass::onVedirectStatus(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentialsReadonly(request)) {
|
if (!WebApi.checkCredentialsReadonly(request)) {
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_webapp.h"
|
#include "WebApi_webapp.h"
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ extern const uint8_t file_site_webmanifest_end[] asm("_binary_webapp_dist_site_w
|
|||||||
#define ETAG_HTTP_HEADER_VAL "\"" AUTO_GIT_HASH "\"" // ETag value must be between quotes
|
#define ETAG_HTTP_HEADER_VAL "\"" AUTO_GIT_HASH "\"" // ETag value must be between quotes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void WebApiWebappClass::init(AsyncWebServer& server)
|
void WebApiWebappClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
_server = &server;
|
_server = &server;
|
||||||
|
|
||||||
@ -94,7 +94,3 @@ void WebApiWebappClass::init(AsyncWebServer& server)
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWebappClass::loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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 "WebApi_ws_Huawei.h"
|
#include "WebApi_ws_Huawei.h"
|
||||||
#include "AsyncJson.h"
|
#include "AsyncJson.h"
|
||||||
@ -16,7 +16,7 @@ WebApiWsHuaweiLiveClass::WebApiWsHuaweiLiveClass()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsHuaweiLiveClass::init(AsyncWebServer& server)
|
void WebApiWsHuaweiLiveClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -30,26 +30,33 @@ void WebApiWsHuaweiLiveClass::init(AsyncWebServer& server)
|
|||||||
|
|
||||||
_server->addHandler(&_ws);
|
_server->addHandler(&_ws);
|
||||||
_ws.onEvent(std::bind(&WebApiWsHuaweiLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
_ws.onEvent(std::bind(&WebApiWsHuaweiLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
|
||||||
|
scheduler.addTask(_wsCleanupTask);
|
||||||
|
_wsCleanupTask.setCallback(std::bind(&WebApiWsHuaweiLiveClass::wsCleanupTaskCb, this));
|
||||||
|
_wsCleanupTask.setIterations(TASK_FOREVER);
|
||||||
|
_wsCleanupTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_wsCleanupTask.enable();
|
||||||
|
|
||||||
|
scheduler.addTask(_sendDataTask);
|
||||||
|
_sendDataTask.setCallback(std::bind(&WebApiWsHuaweiLiveClass::sendDataTaskCb, this));
|
||||||
|
_sendDataTask.setIterations(TASK_FOREVER);
|
||||||
|
_sendDataTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_sendDataTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsHuaweiLiveClass::loop()
|
void WebApiWsHuaweiLiveClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
if (millis() - _lastWsCleanup > 1000) {
|
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
_lastWsCleanup = millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApiWsHuaweiLiveClass::sendDataTaskCb()
|
||||||
|
{
|
||||||
// do nothing if no WS client is connected
|
// do nothing if no WS client is connected
|
||||||
if (_ws.count() == 0) {
|
if (_ws.count() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis() - _lastUpdateCheck < 1000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_lastUpdateCheck = millis();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
DynamicJsonDocument root(1024);
|
DynamicJsonDocument root(1024);
|
||||||
|
|||||||
@ -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 "WebApi_ws_battery.h"
|
#include "WebApi_ws_battery.h"
|
||||||
#include "AsyncJson.h"
|
#include "AsyncJson.h"
|
||||||
@ -16,7 +16,7 @@ WebApiWsBatteryLiveClass::WebApiWsBatteryLiveClass()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsBatteryLiveClass::init(AsyncWebServer& server)
|
void WebApiWsBatteryLiveClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -30,16 +30,28 @@ void WebApiWsBatteryLiveClass::init(AsyncWebServer& server)
|
|||||||
|
|
||||||
_server->addHandler(&_ws);
|
_server->addHandler(&_ws);
|
||||||
_ws.onEvent(std::bind(&WebApiWsBatteryLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
_ws.onEvent(std::bind(&WebApiWsBatteryLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
|
||||||
|
scheduler.addTask(_wsCleanupTask);
|
||||||
|
_wsCleanupTask.setCallback(std::bind(&WebApiWsBatteryLiveClass::wsCleanupTaskCb, this));
|
||||||
|
_wsCleanupTask.setIterations(TASK_FOREVER);
|
||||||
|
_wsCleanupTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_wsCleanupTask.enable();
|
||||||
|
|
||||||
|
scheduler.addTask(_sendDataTask);
|
||||||
|
_sendDataTask.setCallback(std::bind(&WebApiWsBatteryLiveClass::sendDataTaskCb, this));
|
||||||
|
_sendDataTask.setIterations(TASK_FOREVER);
|
||||||
|
_sendDataTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_sendDataTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsBatteryLiveClass::loop()
|
void WebApiWsBatteryLiveClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
if (millis() - _lastWsCleanup > 1000) {
|
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
_lastWsCleanup = millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApiWsBatteryLiveClass::sendDataTaskCb()
|
||||||
|
{
|
||||||
// do nothing if no WS client is connected
|
// do nothing if no WS client is connected
|
||||||
if (_ws.count() == 0) {
|
if (_ws.count() == 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_ws_console.h"
|
#include "WebApi_ws_console.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -10,20 +10,23 @@
|
|||||||
|
|
||||||
WebApiWsConsoleClass::WebApiWsConsoleClass()
|
WebApiWsConsoleClass::WebApiWsConsoleClass()
|
||||||
: _ws("/console")
|
: _ws("/console")
|
||||||
|
, _wsCleanupTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&WebApiWsConsoleClass::wsCleanupTaskCb, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsConsoleClass::init(AsyncWebServer& server)
|
void WebApiWsConsoleClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
_server = &server;
|
_server = &server;
|
||||||
_server->addHandler(&_ws);
|
_server->addHandler(&_ws);
|
||||||
MessageOutput.register_ws_output(&_ws);
|
MessageOutput.register_ws_output(&_ws);
|
||||||
|
|
||||||
|
scheduler.addTask(_wsCleanupTask);
|
||||||
|
_wsCleanupTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsConsoleClass::loop()
|
void WebApiWsConsoleClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
if (millis() - _lastWsCleanup > 1000) {
|
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
if (Configuration.get().Security.AllowReadonly) {
|
||||||
@ -31,7 +34,4 @@ void WebApiWsConsoleClass::loop()
|
|||||||
} else {
|
} else {
|
||||||
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastWsCleanup = millis();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
*/
|
*/
|
||||||
#include "WebApi_ws_live.h"
|
#include "WebApi_ws_live.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
@ -17,10 +17,12 @@
|
|||||||
|
|
||||||
WebApiWsLiveClass::WebApiWsLiveClass()
|
WebApiWsLiveClass::WebApiWsLiveClass()
|
||||||
: _ws("/livedata")
|
: _ws("/livedata")
|
||||||
|
, _wsCleanupTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&WebApiWsLiveClass::wsCleanupTaskCb, this))
|
||||||
|
, _sendDataTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&WebApiWsLiveClass::sendDataTaskCb, this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::init(AsyncWebServer& server)
|
void WebApiWsLiveClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -34,33 +36,37 @@ void WebApiWsLiveClass::init(AsyncWebServer& server)
|
|||||||
|
|
||||||
_server->addHandler(&_ws);
|
_server->addHandler(&_ws);
|
||||||
_ws.onEvent(std::bind(&WebApiWsLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
_ws.onEvent(std::bind(&WebApiWsLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
|
||||||
|
scheduler.addTask(_wsCleanupTask);
|
||||||
|
_wsCleanupTask.enable();
|
||||||
|
|
||||||
|
scheduler.addTask(_sendDataTask);
|
||||||
|
_sendDataTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::loop()
|
void WebApiWsLiveClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
if (millis() - _lastWsCleanup > 1000) {
|
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
_lastWsCleanup = millis();
|
|
||||||
|
if (Configuration.get().Security.AllowReadonly) {
|
||||||
|
_ws.setAuthentication("", "");
|
||||||
|
} else {
|
||||||
|
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApiWsLiveClass::sendDataTaskCb()
|
||||||
|
{
|
||||||
// do nothing if no WS client is connected
|
// do nothing if no WS client is connected
|
||||||
if (_ws.count() == 0) {
|
if (_ws.count() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis() - _lastInvUpdateCheck < 1000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_lastInvUpdateCheck = millis();
|
|
||||||
|
|
||||||
uint32_t maxTimeStamp = 0;
|
uint32_t maxTimeStamp = 0;
|
||||||
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
||||||
auto inv = Hoymiles.getInverterByPos(i);
|
auto inv = Hoymiles.getInverterByPos(i);
|
||||||
|
maxTimeStamp = std::max<uint32_t>(maxTimeStamp, inv->Statistics()->getLastUpdate());
|
||||||
if (inv->Statistics()->getLastUpdate() > maxTimeStamp) {
|
|
||||||
maxTimeStamp = inv->Statistics()->getLastUpdate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update on every inverter change or at least after 10 seconds
|
// Update on every inverter change or at least after 10 seconds
|
||||||
@ -76,13 +82,8 @@ void WebApiWsLiveClass::loop()
|
|||||||
String buffer;
|
String buffer;
|
||||||
serializeJson(root, buffer);
|
serializeJson(root, buffer);
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
|
||||||
_ws.setAuthentication("", "");
|
|
||||||
} else {
|
|
||||||
_ws.setAuthentication(AUTH_USERNAME, Configuration.get().Security.Password);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ws.textAll(buffer);
|
_ws.textAll(buffer);
|
||||||
|
_newestInverterTimestamp = maxTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::bad_alloc& bad_alloc) {
|
} catch (const std::bad_alloc& bad_alloc) {
|
||||||
@ -133,25 +134,25 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
if (t == TYPE_DC) {
|
if (t == TYPE_DC) {
|
||||||
chanTypeObj[String(static_cast<uint8_t>(c))]["name"]["u"] = inv_cfg->channel[c].Name;
|
chanTypeObj[String(static_cast<uint8_t>(c))]["name"]["u"] = inv_cfg->channel[c].Name;
|
||||||
}
|
}
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_PAC);
|
addField(chanTypeObj, inv, t, c, FLD_PAC);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_UAC);
|
addField(chanTypeObj, inv, t, c, FLD_UAC);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_IAC);
|
addField(chanTypeObj, inv, t, c, FLD_IAC);
|
||||||
if (t == TYPE_AC) {
|
if (t == TYPE_AC) {
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_PDC, "Power DC");
|
addField(chanTypeObj, inv, t, c, FLD_PDC, "Power DC");
|
||||||
} else {
|
} else {
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_PDC);
|
addField(chanTypeObj, inv, t, c, FLD_PDC);
|
||||||
}
|
}
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_UDC);
|
addField(chanTypeObj, inv, t, c, FLD_UDC);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_IDC);
|
addField(chanTypeObj, inv, t, c, FLD_IDC);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_YD);
|
addField(chanTypeObj, inv, t, c, FLD_YD);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_YT);
|
addField(chanTypeObj, inv, t, c, FLD_YT);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_F);
|
addField(chanTypeObj, inv, t, c, FLD_F);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_T);
|
addField(chanTypeObj, inv, t, c, FLD_T);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_PF);
|
addField(chanTypeObj, inv, t, c, FLD_PF);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_Q);
|
addField(chanTypeObj, inv, t, c, FLD_Q);
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_EFF);
|
addField(chanTypeObj, inv, t, c, FLD_EFF);
|
||||||
if (t == TYPE_DC && inv->Statistics()->getStringMaxPower(c) > 0) {
|
if (t == TYPE_DC && inv->Statistics()->getStringMaxPower(c) > 0) {
|
||||||
addField(chanTypeObj, i, inv, t, c, FLD_IRR);
|
addField(chanTypeObj, inv, t, c, FLD_IRR);
|
||||||
chanTypeObj[String(c)][inv->Statistics()->getChannelFieldName(t, c, FLD_IRR)]["max"] = inv->Statistics()->getStringMaxPower(c);
|
chanTypeObj[String(c)][inv->Statistics()->getChannelFieldName(t, c, FLD_IRR)]["max"] = inv->Statistics()->getStringMaxPower(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,10 +163,6 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
} else {
|
} else {
|
||||||
invObject["events"] = -1;
|
invObject["events"] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inv->Statistics()->getLastUpdate() > _newestInverterTimestamp) {
|
|
||||||
_newestInverterTimestamp = inv->Statistics()->getLastUpdate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject totalObj = root.createNestedObject("total");
|
JsonObject totalObj = root.createNestedObject("total");
|
||||||
@ -206,7 +203,7 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic)
|
void WebApiWsLiveClass::addField(JsonObject& root, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic)
|
||||||
{
|
{
|
||||||
if (inv->Statistics()->hasChannelFieldValue(type, channel, fieldId)) {
|
if (inv->Statistics()->hasChannelFieldValue(type, channel, fieldId)) {
|
||||||
String chanName;
|
String chanName;
|
||||||
|
|||||||
@ -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 "WebApi_ws_vedirect_live.h"
|
#include "WebApi_ws_vedirect_live.h"
|
||||||
#include "AsyncJson.h"
|
#include "AsyncJson.h"
|
||||||
@ -17,7 +17,7 @@ WebApiWsVedirectLiveClass::WebApiWsVedirectLiveClass()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsVedirectLiveClass::init(AsyncWebServer& server)
|
void WebApiWsVedirectLiveClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
using std::placeholders::_2;
|
using std::placeholders::_2;
|
||||||
@ -31,16 +31,29 @@ void WebApiWsVedirectLiveClass::init(AsyncWebServer& server)
|
|||||||
|
|
||||||
_server->addHandler(&_ws);
|
_server->addHandler(&_ws);
|
||||||
_ws.onEvent(std::bind(&WebApiWsVedirectLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
_ws.onEvent(std::bind(&WebApiWsVedirectLiveClass::onWebsocketEvent, this, _1, _2, _3, _4, _5, _6));
|
||||||
|
|
||||||
|
|
||||||
|
scheduler.addTask(_wsCleanupTask);
|
||||||
|
_wsCleanupTask.setCallback(std::bind(&WebApiWsVedirectLiveClass::wsCleanupTaskCb, this));
|
||||||
|
_wsCleanupTask.setIterations(TASK_FOREVER);
|
||||||
|
_wsCleanupTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_wsCleanupTask.enable();
|
||||||
|
|
||||||
|
scheduler.addTask(_sendDataTask);
|
||||||
|
_sendDataTask.setCallback(std::bind(&WebApiWsVedirectLiveClass::sendDataTaskCb, this));
|
||||||
|
_sendDataTask.setIterations(TASK_FOREVER);
|
||||||
|
_sendDataTask.setInterval(1 * TASK_SECOND);
|
||||||
|
_sendDataTask.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsVedirectLiveClass::loop()
|
void WebApiWsVedirectLiveClass::wsCleanupTaskCb()
|
||||||
{
|
{
|
||||||
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
// see: https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
|
||||||
if (millis() - _lastWsCleanup > 1000) {
|
|
||||||
_ws.cleanupClients();
|
_ws.cleanupClients();
|
||||||
_lastWsCleanup = millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebApiWsVedirectLiveClass::sendDataTaskCb()
|
||||||
|
{
|
||||||
// do nothing if no WS client is connected
|
// do nothing if no WS client is connected
|
||||||
if (_ws.count() == 0) {
|
if (_ws.count() == 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -16,18 +16,18 @@
|
|||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
"bootstrap-icons-vue": "^1.11.1",
|
"bootstrap-icons-vue": "^1.11.1",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"sortablejs": "^1.15.1",
|
"sortablejs": "^1.15.2",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"vue": "^3.4.13",
|
"vue": "^3.4.15",
|
||||||
"vue-i18n": "^9.9.0",
|
"vue-i18n": "^9.9.0",
|
||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^2.0.0",
|
"@intlify/unplugin-vue-i18n": "^2.0.0",
|
||||||
"@rushstack/eslint-patch": "^1.6.1",
|
"@rushstack/eslint-patch": "^1.7.0",
|
||||||
"@tsconfig/node18": "^18.2.2",
|
"@tsconfig/node18": "^18.2.2",
|
||||||
"@types/bootstrap": "^5.2.10",
|
"@types/bootstrap": "^5.2.10",
|
||||||
"@types/node": "^20.11.0",
|
"@types/node": "^20.11.5",
|
||||||
"@types/pulltorefreshjs": "^0.1.7",
|
"@types/pulltorefreshjs": "^0.1.7",
|
||||||
"@types/sortablejs": "^1.15.7",
|
"@types/sortablejs": "^1.15.7",
|
||||||
"@types/spark-md5": "^3.0.4",
|
"@types/spark-md5": "^3.0.4",
|
||||||
@ -38,10 +38,10 @@
|
|||||||
"eslint-plugin-vue": "^9.20.1",
|
"eslint-plugin-vue": "^9.20.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"pulltorefreshjs": "^0.1.22",
|
"pulltorefreshjs": "^0.1.22",
|
||||||
"sass": "^1.69.7",
|
"sass": "^1.70.0",
|
||||||
"terser": "^5.26.0",
|
"terser": "^5.27.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.11",
|
"vite": "^5.0.12",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-css-injected-by-js": "^3.3.1",
|
"vite-plugin-css-injected-by-js": "^3.3.1",
|
||||||
"vue-tsc": "^1.8.27"
|
"vue-tsc": "^1.8.27"
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<NavBar />
|
<NavBar />
|
||||||
<main class="container-fluid">
|
|
||||||
<router-view />
|
<router-view />
|
||||||
</main>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export default defineComponent({
|
|||||||
var self = this;
|
var self = this;
|
||||||
console.log("init");
|
console.log("init");
|
||||||
PullToRefresh.init({
|
PullToRefresh.init({
|
||||||
mainElement: 'main', // above which element?
|
mainElement: 'body', // above which element?
|
||||||
instructionsPullToRefresh: this.$t('base.Pull'),
|
instructionsPullToRefresh: this.$t('base.Pull'),
|
||||||
instructionsReleaseToRefresh: this.$t('base.Release'),
|
instructionsReleaseToRefresh: this.$t('base.Release'),
|
||||||
instructionsRefreshing: this.$t('base.Refreshing'),
|
instructionsRefreshing: this.$t('base.Refreshing'),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['card', addSpace ? 'mt-5' : '' ]">
|
<div :class="['card', addSpace ? 'mt-5' : '' ]">
|
||||||
<div :class="['card-header', textVariant]">{{ text }}</div>
|
<div :class="['card-header', textVariant]">{{ text }}</div>
|
||||||
<div :class="['card-body', centerContent ? 'text-center' : '']">
|
<div :class="['card-body', 'card-text', centerContent ? 'text-center' : '']">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export default defineComponent({
|
|||||||
computed: {
|
computed: {
|
||||||
timeInHours() {
|
timeInHours() {
|
||||||
return (value: number) => {
|
return (value: number) => {
|
||||||
return timestampToString(value);
|
return timestampToString(this.$i18n.locale, value)[0];
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,12 +32,19 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $t('firmwareinfo.FirmwareUpdate') }}</th>
|
<th>{{ $t('firmwareinfo.FirmwareUpdate') }}</th>
|
||||||
<td><a :href="systemStatus.update_url" target="_blank" v-tooltip
|
<td v-if="modelAllowVersionInfo">
|
||||||
|
<a :href="systemStatus.update_url" target="_blank" v-tooltip
|
||||||
:title="$t('firmwareinfo.FirmwareUpdateHint')">
|
:title="$t('firmwareinfo.FirmwareUpdateHint')">
|
||||||
<span class="badge" :class="systemStatus.update_status">
|
<span class="badge" :class="systemStatus.update_status">
|
||||||
{{ systemStatus.update_text }}
|
{{ systemStatus.update_text }}
|
||||||
</span>
|
</span>
|
||||||
</a></td>
|
</a>
|
||||||
|
</td>
|
||||||
|
<td v-else>
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input v-model="modelAllowVersionInfo" class="form-check-input" type="checkbox" role="switch" v-tooltip :title="$t('firmwareinfo.FrmwareUpdateAllow')" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $t('firmwareinfo.ResetReason0') }}</th>
|
<th>{{ $t('firmwareinfo.ResetReason0') }}</th>
|
||||||
@ -53,7 +60,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $t('firmwareinfo.Uptime') }}</th>
|
<th>{{ $t('firmwareinfo.Uptime') }}</th>
|
||||||
<td>{{ timeInHours(systemStatus.uptime) }}</td>
|
<td>{{ $t('firmwareinfo.UptimeValue', timeInHours(systemStatus.uptime)) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -73,11 +80,21 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
|
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
|
||||||
|
allowVersionInfo: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
modelAllowVersionInfo: {
|
||||||
|
get(): any {
|
||||||
|
return !!this.allowVersionInfo;
|
||||||
|
},
|
||||||
|
set(value: any) {
|
||||||
|
this.$emit('update:allowVersionInfo', value);
|
||||||
|
},
|
||||||
|
},
|
||||||
timeInHours() {
|
timeInHours() {
|
||||||
return (value: number) => {
|
return (value: number) => {
|
||||||
return timestampToString(value, true);
|
const [count, time] = timestampToString(this.$i18n.locale, value, true);
|
||||||
|
return {count, time};
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
versionInfoUrl(): string {
|
versionInfoUrl(): string {
|
||||||
|
|||||||
@ -33,9 +33,9 @@
|
|||||||
<tr v-for="value in section.items" :key="value.n">
|
<tr v-for="value in section.items" :key="value.n">
|
||||||
<th>{{ value.n }}</th>
|
<th>{{ value.n }}</th>
|
||||||
<td>
|
<td>
|
||||||
<tempplate v-if="value.u!='bool'">
|
<template v-if="value.u!='bool'">
|
||||||
{{ $n(value.v, 'decimal') }} {{ value.u }}
|
{{ $n(value.v, 'decimal') }} {{ value.u }}
|
||||||
</tempplate>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<StatusBadge :status="value.v==1" true_text="gridprofile.Enabled" false_text="gridprofile.Disabled"/>
|
<StatusBadge :status="value.v==1" true_text="gridprofile.Enabled" false_text="gridprofile.Disabled"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div class="card" :class="{
|
<div class="card" :class="{
|
||||||
'border-info': channelType == 'AC',
|
'border-info': channelType == 'AC',
|
||||||
'border-secondary': channelType == 'INV'
|
'border-secondary': channelType == 'INV'
|
||||||
}">
|
}" style="overflow: hidden">
|
||||||
<div v-if="channelType == 'INV'" class="card-header text-bg-secondary">
|
<div v-if="channelType == 'INV'" class="card-header text-bg-secondary">
|
||||||
{{ $t('inverterchannelinfo.General') }}
|
{{ $t('inverterchannelinfo.General') }}
|
||||||
</div>
|
</div>
|
||||||
@ -16,24 +16,17 @@
|
|||||||
{{ $t('inverterchannelinfo.Phase', { num: channelNumber + 1 }) }}
|
{{ $t('inverterchannelinfo.Phase', { num: channelNumber + 1 }) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover" style="margin: 0">
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ $t('inverterchannelinfo.Property') }}</th>
|
|
||||||
<th style="text-align: right" scope="col">{{ $t('inverterchannelinfo.Value') }}</th>
|
|
||||||
<th scope="col">{{ $t('inverterchannelinfo.Unit') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(property, key) in channelData" :key="`prop-${key}`">
|
<tr v-for="(property, key) in channelData" :key="`prop-${key}`">
|
||||||
<template v-if="key != 'name' && property">
|
<template v-if="key != 'name' && property">
|
||||||
<th scope="row">{{ $t('inverterchannelproperty.' + key) }}</th>
|
<th scope="row">{{ $t('inverterchannelproperty.' + key) }}</th>
|
||||||
<td style="text-align: right">
|
<td style="text-align: right; padding-right: 0;">
|
||||||
{{ $n(property.v, 'decimal', {
|
{{ $n(property.v, 'decimal', {
|
||||||
minimumFractionDigits: property.d,
|
minimumFractionDigits: property.d,
|
||||||
maximumFractionDigits: property.d})
|
maximumFractionDigits: property.d
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ property.u }}</td>
|
<td>{{ property.u }}</td>
|
||||||
@ -43,7 +36,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@ -2,9 +2,7 @@
|
|||||||
<div v-show="totalVeData.enabled">
|
<div v-show="totalVeData.enabled">
|
||||||
<div class="row row-cols-1 row-cols-md-3 g-3">
|
<div class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.MpptTotalYieldTotal')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalYieldTotal') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalVeData.total.YieldTotal.v, 'decimal', {
|
{{ $n(totalVeData.total.YieldTotal.v, 'decimal', {
|
||||||
minimumFractionDigits: totalVeData.total.YieldTotal.d,
|
minimumFractionDigits: totalVeData.total.YieldTotal.d,
|
||||||
@ -12,13 +10,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalVeData.total.YieldTotal.u }}</small>
|
<small class="text-muted">{{ totalVeData.total.YieldTotal.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.MpptTotalYieldDay')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalYieldDay') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalVeData.total.YieldDay.v, 'decimal', {
|
{{ $n(totalVeData.total.YieldDay.v, 'decimal', {
|
||||||
minimumFractionDigits: totalVeData.total.YieldDay.d,
|
minimumFractionDigits: totalVeData.total.YieldDay.d,
|
||||||
@ -26,13 +21,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalVeData.total.YieldDay.u }}</small>
|
<small class="text-muted">{{ totalVeData.total.YieldDay.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.MpptTotalPower')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalPower') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalVeData.total.Power.v, 'decimal', {
|
{{ $n(totalVeData.total.Power.v, 'decimal', {
|
||||||
minimumFractionDigits: totalVeData.total.Power.d,
|
minimumFractionDigits: totalVeData.total.Power.d,
|
||||||
@ -40,16 +32,13 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalVeData.total.Power.u }}</small>
|
<small class="text-muted">{{ totalVeData.total.Power.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-1 row-cols-md-3 g-3">
|
<div class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.TotalYieldTotal')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalYieldTotal') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalData.YieldTotal.v, 'decimal', {
|
{{ $n(totalData.YieldTotal.v, 'decimal', {
|
||||||
minimumFractionDigits: totalData.YieldTotal.d,
|
minimumFractionDigits: totalData.YieldTotal.d,
|
||||||
@ -57,13 +46,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.YieldTotal.u }}</small>
|
<small class="text-muted">{{ totalData.YieldTotal.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.TotalYieldDay')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalYieldDay') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalData.YieldDay.v, 'decimal', {
|
{{ $n(totalData.YieldDay.v, 'decimal', {
|
||||||
minimumFractionDigits: totalData.YieldDay.d,
|
minimumFractionDigits: totalData.YieldDay.d,
|
||||||
@ -71,13 +57,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.YieldDay.u }}</small>
|
<small class="text-muted">{{ totalData.YieldDay.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.TotalPower')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalPower') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalData.Power.v, 'decimal', {
|
{{ $n(totalData.Power.v, 'decimal', {
|
||||||
minimumFractionDigits: totalData.Power.d,
|
minimumFractionDigits: totalData.Power.d,
|
||||||
@ -85,16 +68,13 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.Power.u }}</small>
|
<small class="text-muted">{{ totalData.Power.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="totalBattData.enabled || powerMeterData.enabled || huaweiData.enabled">
|
<div v-show="totalBattData.enabled || powerMeterData.enabled || huaweiData.enabled">
|
||||||
<div class="row row-cols-1 row-cols-md-3 g-3">
|
<div class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
<div class="col" v-show="totalBattData.enabled">
|
<div class="col" v-show="totalBattData.enabled">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.BatterySoc')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.BatterySoc') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(totalBattData.soc.v, 'decimal', {
|
{{ $n(totalBattData.soc.v, 'decimal', {
|
||||||
minimumFractionDigits: totalBattData.soc.d,
|
minimumFractionDigits: totalBattData.soc.d,
|
||||||
@ -102,13 +82,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{ totalBattData.soc.u }}</small>
|
<small class="text-muted">{{ totalBattData.soc.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col" v-show="powerMeterData.enabled">
|
<div class="col" v-show="powerMeterData.enabled">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.HomePower')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.HomePower') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(powerMeterData.Power.v, 'decimal', {
|
{{ $n(powerMeterData.Power.v, 'decimal', {
|
||||||
minimumFractionDigits: powerMeterData.Power.d,
|
minimumFractionDigits: powerMeterData.Power.d,
|
||||||
@ -116,13 +93,10 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{powerMeterData.Power.u }}</small>
|
<small class="text-muted">{{powerMeterData.Power.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col" v-show="huaweiData.enabled">
|
<div class="col" v-show="huaweiData.enabled">
|
||||||
<div class="card">
|
<CardElement centerContent textVariant="text-bg-success" :text="$t('invertertotalinfo.HuaweiPower')">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.HuaweiPower') }}</div>
|
|
||||||
<div class="card-body card-text text-center">
|
|
||||||
<h2>
|
<h2>
|
||||||
{{ $n(huaweiData.Power.v, 'decimal', {
|
{{ $n(huaweiData.Power.v, 'decimal', {
|
||||||
minimumFractionDigits: huaweiData.Power.d,
|
minimumFractionDigits: huaweiData.Power.d,
|
||||||
@ -130,8 +104,7 @@
|
|||||||
}) }}
|
}) }}
|
||||||
<small class="text-muted">{{huaweiData.Power.u }}</small>
|
<small class="text-muted">{{huaweiData.Power.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</CardElement>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -139,9 +112,13 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Battery, Total, Vedirect, Huawei, PowerMeter } from '@/types/LiveDataStatus';
|
import type { Battery, Total, Vedirect, Huawei, PowerMeter } from '@/types/LiveDataStatus';
|
||||||
|
import CardElement from './CardElement.vue';
|
||||||
import { defineComponent, type PropType } from 'vue';
|
import { defineComponent, type PropType } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
CardElement,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
totalData: { type: Object as PropType<Total>, required: true },
|
totalData: { type: Object as PropType<Total>, required: true },
|
||||||
totalVeData: { type: Object as PropType<Vedirect>, required: true },
|
totalVeData: { type: Object as PropType<Vedirect>, required: true },
|
||||||
|
|||||||
52
webapp/src/components/ModalDialog.vue
Normal file
52
webapp/src/components/ModalDialog.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modal" :id="modalId" tabindex="-1">
|
||||||
|
<div class="modal-dialog" :class="[small ? '' : 'modal-lg']">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">{{ title }}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="getCloseText"
|
||||||
|
@click="close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="text-center" v-if="loading">
|
||||||
|
<div class="spinner-border" role="status">
|
||||||
|
<span class="visually-hidden">{{ $t('home.Loading') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot v-else>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<slot name="footer">
|
||||||
|
</slot>
|
||||||
|
<button type="button" class="btn btn-secondary" @click="close" data-bs-dismiss="modal">{{
|
||||||
|
getCloseText }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
'modalId': { type: String, required: true },
|
||||||
|
'title': { type: String, required: true },
|
||||||
|
'closeText': { type: String, required: false, default: '' },
|
||||||
|
'small': Boolean,
|
||||||
|
'loading': Boolean,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getCloseText() {
|
||||||
|
return this.closeText == '' ? this.$t('base.Close') : this.closeText;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@ -1,17 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="navbar navbar-expand-md fixed-top bg-body-tertiary" data-bs-theme="dark">
|
<nav class="navbar navbar-expand-md fixed-top bg-body-tertiary" data-bs-theme="dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<router-link @click="onClick" class="navbar-brand" to="/">
|
<router-link @click="onClick" class="navbar-brand" to="/" style="display: flex; height: 30px; padding: 0;">
|
||||||
<span v-if="isXmas" class="text-success">
|
<BIconTree v-if="isXmas" width="30" height="30" class="d-inline-block align-text-top text-success" />
|
||||||
<BIconTree width="30" height="30" class="d-inline-block align-text-top" />
|
|
||||||
</span>
|
<BIconEgg v-else-if="isEaster" width="30" height="30" class="d-inline-block align-text-top text-info" />
|
||||||
<span v-else-if="isEaster" class="text-info">
|
|
||||||
<BIconEgg width="30" height="30" class="d-inline-block align-text-top" />
|
<BIconSun v-else width="30" height="30" class="d-inline-block align-text-top text-warning" />
|
||||||
</span>
|
|
||||||
<span v-else class="text-warning">
|
<span style="margin-left: .5rem">
|
||||||
<BIconSun width="30" height="30" class="d-inline-block align-text-top" />
|
|
||||||
</span>
|
|
||||||
OpenDTU-onBattery
|
OpenDTU-onBattery
|
||||||
|
</span>
|
||||||
<span class="text-info">
|
<span class="text-info">
|
||||||
<BIconBatteryCharging width="20" height="20" class="d-inline-block align-text-center" />
|
<BIconBatteryCharging width="20" height="20" class="d-inline-block align-text-center" />
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -38,7 +38,8 @@
|
|||||||
"Save": "Speichern",
|
"Save": "Speichern",
|
||||||
"Refreshing": "Aktualisieren",
|
"Refreshing": "Aktualisieren",
|
||||||
"Pull": "Zum Aktualisieren nach unten ziehen",
|
"Pull": "Zum Aktualisieren nach unten ziehen",
|
||||||
"Release": "Loslassen zum Aktualisieren"
|
"Release": "Loslassen zum Aktualisieren",
|
||||||
|
"Close": "Schließen"
|
||||||
},
|
},
|
||||||
"localeswitcher": {
|
"localeswitcher": {
|
||||||
"Dark": "Dunkel",
|
"Dark": "Dunkel",
|
||||||
@ -125,7 +126,6 @@
|
|||||||
"UnreadMessages": "Ungelesene Meldungen",
|
"UnreadMessages": "Ungelesene Meldungen",
|
||||||
"Loading": "@:base.Loading",
|
"Loading": "@:base.Loading",
|
||||||
"EventLog": "Ereignisanzeige",
|
"EventLog": "Ereignisanzeige",
|
||||||
"Close": "Schließen",
|
|
||||||
"InverterInfo": "Wechselrichter-Informationen",
|
"InverterInfo": "Wechselrichter-Informationen",
|
||||||
"LimitSettings": "Limit-Einstellungen",
|
"LimitSettings": "Limit-Einstellungen",
|
||||||
"LastLimitSetStatus": "Letzter Übertragungsstatus:",
|
"LastLimitSetStatus": "Letzter Übertragungsstatus:",
|
||||||
@ -229,10 +229,12 @@
|
|||||||
"FirmwareVersionHint": "Klicken Sie hier, um Informationen über Ihre aktuelle Version anzuzeigen",
|
"FirmwareVersionHint": "Klicken Sie hier, um Informationen über Ihre aktuelle Version anzuzeigen",
|
||||||
"FirmwareUpdate": "Firmware-Aktualisierung",
|
"FirmwareUpdate": "Firmware-Aktualisierung",
|
||||||
"FirmwareUpdateHint": "Klicken Sie hier, um die Änderungen zwischen Ihrer Version und der neuesten Version anzuzeigen",
|
"FirmwareUpdateHint": "Klicken Sie hier, um die Änderungen zwischen Ihrer Version und der neuesten Version anzuzeigen",
|
||||||
|
"FrmwareUpdateAllow": "Durch Aktivieren der Update Prüfung wird bei jedem Seitenaufruf eine Anfrage an GitHub.com gesendet um die aktuell verfügbare Version abzurufen. Wenn du damit nicht einverstanden bist, lasse diese Funktion deaktiviert.",
|
||||||
"ResetReason0": "Reset Grund CPU 0",
|
"ResetReason0": "Reset Grund CPU 0",
|
||||||
"ResetReason1": "Reset Grund CPU 1",
|
"ResetReason1": "Reset Grund CPU 1",
|
||||||
"ConfigSaveCount": "Anzahl der Konfigurationsspeicherungen",
|
"ConfigSaveCount": "Anzahl der Konfigurationsspeicherungen",
|
||||||
"Uptime": "Betriebszeit"
|
"Uptime": "Betriebszeit",
|
||||||
|
"UptimeValue": "0 Tage {time} | 1 Tag {time} | {count} Tage {time}"
|
||||||
},
|
},
|
||||||
"hardwareinfo": {
|
"hardwareinfo": {
|
||||||
"HardwareInformation": "Hardwareinformationen",
|
"HardwareInformation": "Hardwareinformationen",
|
||||||
@ -371,10 +373,7 @@
|
|||||||
"inverterchannelinfo": {
|
"inverterchannelinfo": {
|
||||||
"String": "String {num}",
|
"String": "String {num}",
|
||||||
"Phase": "Phase {num}",
|
"Phase": "Phase {num}",
|
||||||
"General": "Allgemein",
|
"General": "Allgemein"
|
||||||
"Property": "Eigenschaft",
|
|
||||||
"Value": "Wert",
|
|
||||||
"Unit": "Einheit"
|
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"InverterTotalYieldTotal": "Inverter Gesamtertrag Insgesamt",
|
"InverterTotalYieldTotal": "Inverter Gesamtertrag Insgesamt",
|
||||||
@ -422,7 +421,7 @@
|
|||||||
"CmtPaLevel": "CMT2300A Sendeleistung:",
|
"CmtPaLevel": "CMT2300A Sendeleistung:",
|
||||||
"NrfPaLevelHint": "Verwendet für HM-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
|
"NrfPaLevelHint": "Verwendet für HM-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
|
||||||
"CmtPaLevelHint": "Verwendet für HMS/HMT-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
|
"CmtPaLevelHint": "Verwendet für HMS/HMT-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
|
||||||
"CmtCountry": "Region/Land:",
|
"CmtCountry": "CMT2300A Region/Land:",
|
||||||
"CmtCountryHint": "Jedes Land hat unterschiedliche Frequenzzuteilungen.",
|
"CmtCountryHint": "Jedes Land hat unterschiedliche Frequenzzuteilungen.",
|
||||||
"country_0": "Europa ({min}MHz - {max}MHz)",
|
"country_0": "Europa ({min}MHz - {max}MHz)",
|
||||||
"country_1": "Nordamerika ({min}MHz - {max}MHz)",
|
"country_1": "Nordamerika ({min}MHz - {max}MHz)",
|
||||||
@ -716,7 +715,7 @@
|
|||||||
"Back": "Zurück",
|
"Back": "Zurück",
|
||||||
"Retry": "Wiederholen",
|
"Retry": "Wiederholen",
|
||||||
"OtaStatus": "OTA-Status",
|
"OtaStatus": "OTA-Status",
|
||||||
"OtaSuccess": "OTA erfolgreich. Das Gerät wurde automatisch neu gestartet und wird in wenigen Augenblicken wieder zur Verfügung stehen. Bitte nicht vergessen, die Weboberfläche neu zu laden!",
|
"OtaSuccess": "Das Hochladen der Firmware war erfolgreich. Das Gerät wurde automatisch neu gestartet. Wenn das Gerät wieder erreichbar ist wird die automatisch Oberfläche neu geladen.",
|
||||||
"FirmwareUpload": "Firmware hochladen",
|
"FirmwareUpload": "Firmware hochladen",
|
||||||
"UploadProgress": "Hochlade-Fortschritt"
|
"UploadProgress": "Hochlade-Fortschritt"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -38,7 +38,8 @@
|
|||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"Refreshing": "Refreshing",
|
"Refreshing": "Refreshing",
|
||||||
"Pull": "Pull down to refresh",
|
"Pull": "Pull down to refresh",
|
||||||
"Release": "Release to refresh"
|
"Release": "Release to refresh",
|
||||||
|
"Close": "Close"
|
||||||
},
|
},
|
||||||
"localeswitcher": {
|
"localeswitcher": {
|
||||||
"Dark": "Dark",
|
"Dark": "Dark",
|
||||||
@ -125,7 +126,6 @@
|
|||||||
"UnreadMessages": "unread messages",
|
"UnreadMessages": "unread messages",
|
||||||
"Loading": "@:base.Loading",
|
"Loading": "@:base.Loading",
|
||||||
"EventLog": "Event Log",
|
"EventLog": "Event Log",
|
||||||
"Close": "Close",
|
|
||||||
"InverterInfo": "Inverter Info",
|
"InverterInfo": "Inverter Info",
|
||||||
"LimitSettings": "Limit Settings",
|
"LimitSettings": "Limit Settings",
|
||||||
"LastLimitSetStatus": "Last Limit Set Status:",
|
"LastLimitSetStatus": "Last Limit Set Status:",
|
||||||
@ -230,10 +230,12 @@
|
|||||||
"FirmwareVersionHint": "Click here to show information about your current version",
|
"FirmwareVersionHint": "Click here to show information about your current version",
|
||||||
"FirmwareUpdate": "Firmware Update",
|
"FirmwareUpdate": "Firmware Update",
|
||||||
"FirmwareUpdateHint": "Click here to view the changes between your version and the latest version",
|
"FirmwareUpdateHint": "Click here to view the changes between your version and the latest version",
|
||||||
|
"FrmwareUpdateAllow": "By activating the update check, a request is sent to GitHub.com each time the page is called up to retrieve the currently available version. If you do not agree with this, leave this function deactivated.",
|
||||||
"ResetReason0": "Reset Reason CPU 0",
|
"ResetReason0": "Reset Reason CPU 0",
|
||||||
"ResetReason1": "Reset Reason CPU 1",
|
"ResetReason1": "Reset Reason CPU 1",
|
||||||
"ConfigSaveCount": "Config save count",
|
"ConfigSaveCount": "Config save count",
|
||||||
"Uptime": "Uptime"
|
"Uptime": "Uptime",
|
||||||
|
"UptimeValue": "0 days {time} | 1 day {time} | {count} days {time}"
|
||||||
},
|
},
|
||||||
"hardwareinfo": {
|
"hardwareinfo": {
|
||||||
"HardwareInformation": "Hardware Information",
|
"HardwareInformation": "Hardware Information",
|
||||||
@ -373,10 +375,7 @@
|
|||||||
"inverterchannelinfo": {
|
"inverterchannelinfo": {
|
||||||
"String": "String {num}",
|
"String": "String {num}",
|
||||||
"Phase": "Phase {num}",
|
"Phase": "Phase {num}",
|
||||||
"General": "General",
|
"General": "General"
|
||||||
"Property": "Property",
|
|
||||||
"Value": "Value",
|
|
||||||
"Unit": "Unit"
|
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"InverterTotalYieldTotal": "Inverter Total Yield Total",
|
"InverterTotalYieldTotal": "Inverter Total Yield Total",
|
||||||
@ -424,7 +423,7 @@
|
|||||||
"CmtPaLevel": "CMT2300A Transmitting power:",
|
"CmtPaLevel": "CMT2300A Transmitting power:",
|
||||||
"NrfPaLevelHint": "Used for HM-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
|
"NrfPaLevelHint": "Used for HM-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
|
||||||
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
|
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
|
||||||
"CmtCountry": "Region/Country:",
|
"CmtCountry": "CMT2300A Region/Country:",
|
||||||
"CmtCountryHint": "Each country has different frequency allocations.",
|
"CmtCountryHint": "Each country has different frequency allocations.",
|
||||||
"country_0": "Europe ({min}MHz - {max}MHz)",
|
"country_0": "Europe ({min}MHz - {max}MHz)",
|
||||||
"country_1": "North America ({min}MHz - {max}MHz)",
|
"country_1": "North America ({min}MHz - {max}MHz)",
|
||||||
@ -725,7 +724,7 @@
|
|||||||
"Back": "Back",
|
"Back": "Back",
|
||||||
"Retry": "Retry",
|
"Retry": "Retry",
|
||||||
"OtaStatus": "OTA Status",
|
"OtaStatus": "OTA Status",
|
||||||
"OtaSuccess": "OTA Success. The unit has been automatically restarted and will be available again in a few moments. Please do not forget to reload the web interface!",
|
"OtaSuccess": "The firmware upload was successful. The device was restarted automatically. When the device is accessible again, the interface is automatically reloaded.",
|
||||||
"FirmwareUpload": "Firmware Upload",
|
"FirmwareUpload": "Firmware Upload",
|
||||||
"UploadProgress": "Upload Progress"
|
"UploadProgress": "Upload Progress"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -38,7 +38,8 @@
|
|||||||
"Save": "Sauvegarder",
|
"Save": "Sauvegarder",
|
||||||
"Refreshing": "Refreshing",
|
"Refreshing": "Refreshing",
|
||||||
"Pull": "Pull down to refresh",
|
"Pull": "Pull down to refresh",
|
||||||
"Release": "Release to refresh"
|
"Release": "Release to refresh",
|
||||||
|
"Close": "Fermer"
|
||||||
},
|
},
|
||||||
"localeswitcher": {
|
"localeswitcher": {
|
||||||
"Dark": "Sombre",
|
"Dark": "Sombre",
|
||||||
@ -125,7 +126,6 @@
|
|||||||
"UnreadMessages": "messages non lus",
|
"UnreadMessages": "messages non lus",
|
||||||
"Loading": "@:base.Loading",
|
"Loading": "@:base.Loading",
|
||||||
"EventLog": "Journal des événements",
|
"EventLog": "Journal des événements",
|
||||||
"Close": "Fermer",
|
|
||||||
"InverterInfo": "Informations sur l'onduleur",
|
"InverterInfo": "Informations sur l'onduleur",
|
||||||
"LimitSettings": "Paramètres de la limite",
|
"LimitSettings": "Paramètres de la limite",
|
||||||
"LastLimitSetStatus": "Statut de la dernière limite fixée",
|
"LastLimitSetStatus": "Statut de la dernière limite fixée",
|
||||||
@ -229,10 +229,12 @@
|
|||||||
"FirmwareVersionHint": "Cliquez ici pour afficher des informations sur votre version actuelle",
|
"FirmwareVersionHint": "Cliquez ici pour afficher des informations sur votre version actuelle",
|
||||||
"FirmwareUpdate": "Mise à jour du firmware",
|
"FirmwareUpdate": "Mise à jour du firmware",
|
||||||
"FirmwareUpdateHint": "Cliquez ici pour voir les changements entre votre version et la dernière version",
|
"FirmwareUpdateHint": "Cliquez ici pour voir les changements entre votre version et la dernière version",
|
||||||
|
"FrmwareUpdateAllow": "En activant le contrôle de mise à jour, une demande est envoyée à GitHub.com à chaque fois que la page est consultée afin de récupérer la dernière version disponible. Si tu n'es pas d'accord, laisse cette fonction désactivée.",
|
||||||
"ResetReason0": "Raison de la réinitialisation CPU 0",
|
"ResetReason0": "Raison de la réinitialisation CPU 0",
|
||||||
"ResetReason1": "Raison de la réinitialisation CPU 1",
|
"ResetReason1": "Raison de la réinitialisation CPU 1",
|
||||||
"ConfigSaveCount": "Nombre d'enregistrements de la configuration",
|
"ConfigSaveCount": "Nombre d'enregistrements de la configuration",
|
||||||
"Uptime": "Temps de fonctionnement"
|
"Uptime": "Durée de fonctionnement",
|
||||||
|
"UptimeValue": "0 jour {time} | 1 jour {time} | {count} jours {time}"
|
||||||
},
|
},
|
||||||
"hardwareinfo": {
|
"hardwareinfo": {
|
||||||
"HardwareInformation": "Informations sur le matériel",
|
"HardwareInformation": "Informations sur le matériel",
|
||||||
@ -371,10 +373,7 @@
|
|||||||
"inverterchannelinfo": {
|
"inverterchannelinfo": {
|
||||||
"String": "Ligne {num}",
|
"String": "Ligne {num}",
|
||||||
"Phase": "Phase {num}",
|
"Phase": "Phase {num}",
|
||||||
"General": "General",
|
"General": "General"
|
||||||
"Property": "Propriété",
|
|
||||||
"Value": "Valeur",
|
|
||||||
"Unit": "Unité"
|
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"InverterTotalYieldTotal": "Onduleurs rendement total",
|
"InverterTotalYieldTotal": "Onduleurs rendement total",
|
||||||
@ -422,7 +421,7 @@
|
|||||||
"CmtPaLevel": "CMT2300A Niveau de puissance d'émission",
|
"CmtPaLevel": "CMT2300A Niveau de puissance d'émission",
|
||||||
"NrfPaLevelHint": "Used for HM-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
|
"NrfPaLevelHint": "Used for HM-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
|
||||||
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
|
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
|
||||||
"CmtCountry": "Region/Country:",
|
"CmtCountry": "CMT2300A Region/Country:",
|
||||||
"CmtCountryHint": "Each country has different frequency allocations.",
|
"CmtCountryHint": "Each country has different frequency allocations.",
|
||||||
"country_0": "Europe ({min}MHz - {max}MHz)",
|
"country_0": "Europe ({min}MHz - {max}MHz)",
|
||||||
"country_1": "North America ({min}MHz - {max}MHz)",
|
"country_1": "North America ({min}MHz - {max}MHz)",
|
||||||
@ -683,7 +682,7 @@
|
|||||||
"Back": "Retour",
|
"Back": "Retour",
|
||||||
"Retry": "Réessayer",
|
"Retry": "Réessayer",
|
||||||
"OtaStatus": "Statut OTA",
|
"OtaStatus": "Statut OTA",
|
||||||
"OtaSuccess": "Succès de l'OTA. L'unité a été automatiquement redémarrée et sera à nouveau disponible dans quelques instants. N'oubliez pas de recharger l'interface web !",
|
"OtaSuccess": "Le téléchargement du firmware a réussi. L'appareil a été redémarré automatiquement. Lorsque l'appareil est à nouveau accessible, l'interface est automatiquement rechargée.",
|
||||||
"FirmwareUpload": "Téléversement du firmware",
|
"FirmwareUpload": "Téléversement du firmware",
|
||||||
"UploadProgress": "Progression du téléversement"
|
"UploadProgress": "Progression du téléversement"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Import all of Bootstrap's CSS
|
// Import all of Bootstrap's CSS
|
||||||
@import "~bootstrap/scss/bootstrap";
|
@import "~bootstrap/scss/bootstrap";
|
||||||
|
|
||||||
main {
|
.container-fluid .row {
|
||||||
font-feature-settings: "tnum";
|
font-feature-settings: "tnum";
|
||||||
}
|
}
|
||||||
22
webapp/src/types/InverterConfig.ts
Normal file
22
webapp/src/types/InverterConfig.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export interface InverterChannel {
|
||||||
|
name: string;
|
||||||
|
max_power: number;
|
||||||
|
yield_total_offset: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Inverter {
|
||||||
|
id: string;
|
||||||
|
serial: number;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
order: number;
|
||||||
|
poll_enable: boolean;
|
||||||
|
poll_enable_night: boolean;
|
||||||
|
command_enable: boolean;
|
||||||
|
command_enable_night: boolean;
|
||||||
|
reachable_threshold: number;
|
||||||
|
zero_runtime: boolean;
|
||||||
|
zero_day: boolean;
|
||||||
|
yieldday_correction: boolean;
|
||||||
|
channel: Array<InverterChannel>;
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
export const timestampToString = (timestampSeconds: number, includeDays = false): string => {
|
export function timestampToString(locale: string, timestampSeconds: number, includeDays: true): [number, string];
|
||||||
const timeString = new Date(timestampSeconds * 1000).toLocaleTimeString([], { timeZone: "UTC" });
|
export function timestampToString(locale: string, timestampSeconds: number, includeDays?: false): [string];
|
||||||
if (!includeDays) return timeString;
|
export function timestampToString(locale: string, timestampSeconds: number, includeDays = false): [number, string] | [string] {
|
||||||
|
const timeString = new Date(timestampSeconds * 1000).toLocaleTimeString(locale, { timeZone: "UTC", hour12: false });
|
||||||
|
if (!includeDays) return [timeString];
|
||||||
|
|
||||||
const secondsPerDay = 60 * 60 * 24;
|
const secondsPerDay = 60 * 60 * 24;
|
||||||
const days = Math.floor(timestampSeconds / secondsPerDay);
|
const days = Math.floor(timestampSeconds / secondsPerDay);
|
||||||
return new Intl.RelativeTimeFormat().format(-days, "day") + " " + timeString;
|
return [days, timeString];
|
||||||
}
|
}
|
||||||
@ -88,32 +88,21 @@
|
|||||||
</CardElement>
|
</CardElement>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|
||||||
<div class="modal" id="factoryReset" tabindex="-1">
|
<ModalDialog modalId="factoryReset" small :title="$t('configadmin.FactoryReset')" :closeText="$t('configadmin.Cancel')">
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">{{ $t('configadmin.FactoryReset') }}</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
{{ $t('configadmin.ResetMsg') }}
|
{{ $t('configadmin.ResetMsg') }}
|
||||||
</div>
|
<template #footer>
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" @click="onFactoryResetCancel"
|
|
||||||
data-bs-dismiss="modal">{{ $t('configadmin.Cancel') }}</button>
|
|
||||||
<button type="button" class="btn btn-danger" @click="onFactoryResetPerform">
|
<button type="button" class="btn btn-danger" @click="onFactoryResetPerform">
|
||||||
{{ $t('configadmin.ResetConfirm') }}
|
{{ $t('configadmin.ResetConfirm') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</ModalDialog>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import BasePage from '@/components/BasePage.vue';
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import CardElement from '@/components/CardElement.vue';
|
import CardElement from '@/components/CardElement.vue';
|
||||||
|
import ModalDialog from '@/components/ModalDialog.vue';
|
||||||
import type { ConfigFileList } from '@/types/Config';
|
import type { ConfigFileList } from '@/types/Config';
|
||||||
import { authHeader, handleResponse } from '@/utils/authentication';
|
import { authHeader, handleResponse } from '@/utils/authentication';
|
||||||
import * as bootstrap from 'bootstrap';
|
import * as bootstrap from 'bootstrap';
|
||||||
@ -129,6 +118,7 @@ export default defineComponent({
|
|||||||
BasePage,
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
CardElement,
|
CardElement,
|
||||||
|
ModalDialog,
|
||||||
BIconArrowLeft,
|
BIconArrowLeft,
|
||||||
BIconCheckCircle,
|
BIconCheckCircle,
|
||||||
BIconExclamationCircleFill,
|
BIconExclamationCircleFill,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user