Merge branch 'MalteSchm-webinterface_summary_updates' into development
This commit is contained in:
commit
09fb0618b4
@ -16,7 +16,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EMPTY_WHEN_FULL= 0,
|
EMPTY_WHEN_FULL= 0,
|
||||||
EMPTY_AT_NIGTH
|
EMPTY_AT_NIGHT
|
||||||
} batDrainStrategy;
|
} batDrainStrategy;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
#define VE_MAX_VALUE_LEN 33 // VE.Direct Protocol: max value size is 33 including /0
|
#define VE_MAX_VALUE_LEN 33 // VE.Direct Protocol: max value size is 33 including /0
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t PID; // pruduct id
|
uint16_t PID; // product id
|
||||||
char SER[VE_MAX_VALUE_LEN]; // serial number
|
char SER[VE_MAX_VALUE_LEN]; // serial number
|
||||||
char FW[VE_MAX_VALUE_LEN]; // firmware release number
|
char FW[VE_MAX_VALUE_LEN]; // firmware release number
|
||||||
bool LOAD; // virtual load output state (on if battery voltage reaches upper limit, off if battery reaches lower limit)
|
bool LOAD; // virtual load output state (on if battery voltage reaches upper limit, off if battery reaches lower limit)
|
||||||
|
|||||||
@ -105,7 +105,7 @@ void PowerLimiterClass::loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!canUseDirectSolarPower()) {
|
if (!canUseDirectSolarPower()) {
|
||||||
if (config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGTH)
|
if (config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGHT)
|
||||||
_plState = STATE_NORMAL_OPERATION;
|
_plState = STATE_NORMAL_OPERATION;
|
||||||
else
|
else
|
||||||
_plState = STATE_OFF;
|
_plState = STATE_OFF;
|
||||||
@ -122,7 +122,7 @@ void PowerLimiterClass::loop()
|
|||||||
_plState = STATE_OFF;
|
_plState = STATE_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (canUseDirectSolarPower() && (config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGTH)) {
|
if (canUseDirectSolarPower() && (config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGHT)) {
|
||||||
_plState = STATE_CONSUME_SOLAR_POWER_ONLY;
|
_plState = STATE_CONSUME_SOLAR_POWER_ONLY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
|
#include "Battery.h"
|
||||||
|
#include "VeDirectFrameHandler.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include <AsyncJson.h>
|
#include <AsyncJson.h>
|
||||||
|
|
||||||
@ -186,13 +188,17 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
|
|
||||||
JsonObject vedirectObj = root.createNestedObject("vedirect");
|
JsonObject vedirectObj = root.createNestedObject("vedirect");
|
||||||
vedirectObj[F("enabled")] = Configuration.get().Vedirect_Enabled;
|
vedirectObj[F("enabled")] = Configuration.get().Vedirect_Enabled;
|
||||||
|
JsonObject totalVeObj = vedirectObj.createNestedObject("total");
|
||||||
|
addTotalField(totalVeObj, "Power", VeDirect.veFrame.PPV, "W", 1);
|
||||||
|
addTotalField(totalVeObj, "YieldDay", VeDirect.veFrame.H20 * 1000, "Wh", 0);
|
||||||
|
addTotalField(totalVeObj, "YieldTotal", VeDirect.veFrame.H19, "kWh", 2);
|
||||||
|
|
||||||
JsonObject huaweiObj = root.createNestedObject("huawei");
|
JsonObject huaweiObj = root.createNestedObject("huawei");
|
||||||
huaweiObj[F("enabled")] = Configuration.get().Huawei_Enabled;
|
huaweiObj[F("enabled")] = Configuration.get().Huawei_Enabled;
|
||||||
|
|
||||||
JsonObject batteryObj = root.createNestedObject("battery");
|
JsonObject batteryObj = root.createNestedObject("battery");
|
||||||
batteryObj[F("enabled")] = Configuration.get().Battery_Enabled;
|
batteryObj[F("enabled")] = Configuration.get().Battery_Enabled;
|
||||||
|
addTotalField(batteryObj, "soc", Battery.stateOfCharge, "%", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic)
|
void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic)
|
||||||
|
|||||||
@ -1,14 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<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">
|
<div class="card">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.TotalYieldTotal') }}</div>
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalYieldTotal') }}</div>
|
||||||
|
<div class="card-body card-text text-center">
|
||||||
|
<h2>
|
||||||
|
{{ $n(totalVeData.total.YieldTotal.v, 'decimal', {
|
||||||
|
minimumFractionDigits: totalVeData.total.YieldTotal.d,
|
||||||
|
maximumFractionDigits: totalVeData.total.YieldTotal.d
|
||||||
|
}) }}
|
||||||
|
<small class="text-muted">{{ totalVeData.total.YieldTotal.u }}</small>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalYieldDay') }}</div>
|
||||||
|
<div class="card-body card-text text-center">
|
||||||
|
<h2>
|
||||||
|
{{ $n(totalVeData.total.YieldDay.v, 'decimal', {
|
||||||
|
minimumFractionDigits: totalVeData.total.YieldDay.d,
|
||||||
|
maximumFractionDigits: totalVeData.total.YieldDay.d
|
||||||
|
}) }}
|
||||||
|
<small class="text-muted">{{ totalVeData.total.YieldDay.u }}</small>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.MpptTotalPower') }}</div>
|
||||||
|
<div class="card-body card-text text-center">
|
||||||
|
<h2>
|
||||||
|
{{ $n(totalVeData.total.Power.v, 'decimal', {
|
||||||
|
minimumFractionDigits: totalVeData.total.Power.d,
|
||||||
|
maximumFractionDigits: totalVeData.total.Power.d
|
||||||
|
}) }}
|
||||||
|
<small class="text-muted">{{ totalVeData.total.Power.u }}</small>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalYieldTotal') }}</div>
|
||||||
<div class="card-body card-text text-center">
|
<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,
|
||||||
maximumFractionDigits: totalData.YieldTotal.d
|
maximumFractionDigits: totalData.YieldTotal.d
|
||||||
})}}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.YieldTotal.u }}</small>
|
<small class="text-muted">{{ totalData.YieldTotal.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -16,13 +62,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.TotalYieldDay') }}</div>
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalYieldDay') }}</div>
|
||||||
<div class="card-body card-text text-center">
|
<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,
|
||||||
maximumFractionDigits: totalData.YieldDay.d
|
maximumFractionDigits: totalData.YieldDay.d
|
||||||
})}}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.YieldDay.u }}</small>
|
<small class="text-muted">{{ totalData.YieldDay.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -30,28 +76,48 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.TotalPower') }}</div>
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.InverterTotalPower') }}</div>
|
||||||
<div class="card-body card-text text-center">
|
<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,
|
||||||
maximumFractionDigits: totalData.Power.d
|
maximumFractionDigits: totalData.Power.d
|
||||||
})}}
|
}) }}
|
||||||
<small class="text-muted">{{ totalData.Power.u }}</small>
|
<small class="text-muted">{{ totalData.Power.u }}</small>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-show="totalBattData.enabled">
|
||||||
|
<div class="row row-cols-1 row-cols-md-3 g-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-bg-success">{{ $t('invertertotalinfo.BatterySoc') }}</div>
|
||||||
|
<div class="card-body card-text text-center">
|
||||||
|
<h2>
|
||||||
|
{{ $n(totalBattData.soc.v, 'decimal', {
|
||||||
|
minimumFractionDigits: totalBattData.soc.d,
|
||||||
|
maximumFractionDigits: totalBattData.soc.d
|
||||||
|
}) }}
|
||||||
|
<small class="text-muted">{{ totalBattData.soc.u }}</small>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Total } from '@/types/LiveDataStatus';
|
import type { Battery, Total, Vedirect } from '@/types/LiveDataStatus';
|
||||||
import { defineComponent, type PropType } from 'vue';
|
import { defineComponent, type PropType } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
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 },
|
||||||
|
totalBattData: { type: Object as PropType<Battery>, required: true },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -326,9 +326,13 @@
|
|||||||
"Unit": "Einheit"
|
"Unit": "Einheit"
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"TotalYieldTotal": "Gesamtertrag Insgesamt",
|
"InverterTotalYieldTotal": "Inverter Gesamtertrag Insgesamt",
|
||||||
"TotalYieldDay": "Gesamtertrag Heute",
|
"InverterTotalYieldDay": "Inverter Gesamtertrag Heute",
|
||||||
"TotalPower": "Gesamtleistung"
|
"InverterTotalPower": "Inverter Gesamtleistung",
|
||||||
|
"MpptTotalYieldTotal": "MPPT Gesamtertrag Insgesamt",
|
||||||
|
"MpptTotalYieldDay": "MPPT Gesamtertrag Heute",
|
||||||
|
"MpptTotalPower": "MPPT Gesamtleistung",
|
||||||
|
"BatterySoc": "Ladezustand"
|
||||||
},
|
},
|
||||||
"inverterchannelproperty": {
|
"inverterchannelproperty": {
|
||||||
"Power": "Leistung",
|
"Power": "Leistung",
|
||||||
|
|||||||
@ -326,9 +326,13 @@
|
|||||||
"Unit": "Unit"
|
"Unit": "Unit"
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"TotalYieldTotal": "Total Yield Total",
|
"InverterTotalYieldTotal": "Inverter Total Yield Total",
|
||||||
"TotalYieldDay": "Total Yield Day",
|
"InverterTotalYieldDay": "Inverter Total Yield Day",
|
||||||
"TotalPower": "Total Power"
|
"InverterTotalPower": "Inverter Total Power",
|
||||||
|
"MpptTotalYieldTotal": "MPPT Total Yield Total",
|
||||||
|
"MpptTotalYieldDay": "MPPT Total Yield Day",
|
||||||
|
"MpptTotalPower": "MPPT Total Power",
|
||||||
|
"BatterySoc": "State of charge"
|
||||||
},
|
},
|
||||||
"inverterchannelproperty": {
|
"inverterchannelproperty": {
|
||||||
"Power": "Power",
|
"Power": "Power",
|
||||||
|
|||||||
@ -325,9 +325,13 @@
|
|||||||
"Unit": "Unité"
|
"Unit": "Unité"
|
||||||
},
|
},
|
||||||
"invertertotalinfo": {
|
"invertertotalinfo": {
|
||||||
"TotalYieldTotal": "Rendement total",
|
"InverterTotalYieldTotal": "Onduleurs rendement total",
|
||||||
"TotalYieldDay": "Rendement du jour",
|
"InverterTotalYieldDay": "Onduleurs rendement du jour",
|
||||||
"TotalPower": "Puissance de l'installation"
|
"InverterTotalPower": "Onduleurs puissance de l'installation",
|
||||||
|
"MpptTotalYieldTotal": "MPPT rendement total",
|
||||||
|
"MpptTotalYieldDay": "MPPT rendement du jour",
|
||||||
|
"MpptTotalPower": "MPPT puissance de l'installation",
|
||||||
|
"BatterySoc": "State of charge"
|
||||||
},
|
},
|
||||||
"inverterchannelproperty": {
|
"inverterchannelproperty": {
|
||||||
"Power": "Puissance",
|
"Power": "Puissance",
|
||||||
|
|||||||
@ -49,6 +49,7 @@ export interface Hints {
|
|||||||
|
|
||||||
export interface Vedirect {
|
export interface Vedirect {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
total: Total;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Huawei {
|
export interface Huawei {
|
||||||
@ -57,6 +58,7 @@ export interface Huawei {
|
|||||||
|
|
||||||
export interface Battery {
|
export interface Battery {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
soc: ValueObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LiveData {
|
export interface LiveData {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage :title="$t('home.LiveData')" :isLoading="dataLoading" :isWideScreen="true">
|
<BasePage :title="$t('home.LiveData')" :isLoading="dataLoading" :isWideScreen="true">
|
||||||
<HintView :hints="liveData.hints" />
|
<HintView :hints="liveData.hints" />
|
||||||
<InverterTotalInfo :totalData="liveData.total" /><br />
|
<InverterTotalInfo :totalData="liveData.total" :totalVeData="liveData.vedirect" :totalBattData="liveData.battery"/><br />
|
||||||
<div class="row gy-3">
|
<div class="row gy-3">
|
||||||
<div class="col-sm-3 col-md-2" :style="[inverterData.length == 1 ? { 'display': 'none' } : {}]">
|
<div class="col-sm-3 col-md-2" :style="[inverterData.length == 1 ? { 'display': 'none' } : {}]">
|
||||||
<div class="nav nav-pills row-cols-sm-1" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
<div class="nav nav-pills row-cols-sm-1" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user