[Request] Show actual power limiter state in live view helgeerbe/OpenDTU-OnBattery#134

This commit is contained in:
helgeerbe 2023-03-10 16:29:00 +01:00
parent 7952becd17
commit 01a2ffaed5
7 changed files with 58 additions and 5 deletions

View File

@ -7,18 +7,20 @@
#include <Hoymiles.h> #include <Hoymiles.h>
#include <memory> #include <memory>
enum PowerLimiterStates { typedef enum {
STATE_DISCOVER = 0, STATE_DISCOVER = 0,
STATE_OFF, STATE_OFF,
STATE_CONSUME_SOLAR_POWER_ONLY, STATE_CONSUME_SOLAR_POWER_ONLY,
STATE_NORMAL_OPERATION STATE_NORMAL_OPERATION
}; } plStates;
class PowerLimiterClass { class PowerLimiterClass {
public: public:
void init(); void init();
void loop(); void loop();
plStates getPowerLimiterState();
uint16_t getLastRequestedPowewrLimit();
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total); void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
private: private:
@ -26,7 +28,7 @@ private:
uint32_t _lastLoop; uint32_t _lastLoop;
uint32_t _lastPowerMeterUpdate; uint32_t _lastPowerMeterUpdate;
uint16_t _lastRequestedPowerLimit; uint16_t _lastRequestedPowerLimit;
u_int8_t _plState = STATE_DISCOVER; plStates _plState = STATE_DISCOVER;
float _powerMeter1Power; float _powerMeter1Power;
float _powerMeter2Power; float _powerMeter2Power;

View File

@ -186,6 +186,14 @@ void PowerLimiterClass::loop()
} }
} }
plStates PowerLimiterClass::getPowerLimiterState() {
return _plState;
}
uint16_t PowerLimiterClass::getLastRequestedPowewrLimit() {
return _lastRequestedPowerLimit;
}
bool PowerLimiterClass::canUseDirectSolarPower() bool PowerLimiterClass::canUseDirectSolarPower()
{ {
CONFIG_T& config = Configuration.get(); CONFIG_T& config = Configuration.get();

View File

@ -8,6 +8,7 @@
#include "MessageOutput.h" #include "MessageOutput.h"
#include "WebApi.h" #include "WebApi.h"
#include "defaults.h" #include "defaults.h"
#include "PowerLimiter.h"
WebApiWsVedirectLiveClass::WebApiWsVedirectLiveClass() WebApiWsVedirectLiveClass::WebApiWsVedirectLiveClass()
: _ws("/vedirectlivedata") : _ws("/vedirectlivedata")
@ -120,6 +121,13 @@ void WebApiWsVedirectLiveClass::generateJsonResponse(JsonVariant& root)
root["H23"]["v"] = VeDirect.veFrame.H23; root["H23"]["v"] = VeDirect.veFrame.H23;
root["H23"]["u"] = "W"; root["H23"]["u"] = "W";
// power limiter state
if (Configuration.get().PowerLimiter_Enabled)
root["PLSTATE"] = PowerLimiter.getPowerLimiterState();
else
root["PLSTATE"] = -1;
root["PLLIMIT"] = PowerLimiter.getLastRequestedPowewrLimit();
if (VeDirect.getLastUpdate() > _newestVedirectTimestamp) { if (VeDirect.getLastUpdate() > _newestVedirectTimestamp) {
_newestVedirectTimestamp = VeDirect.getLastUpdate(); _newestVedirectTimestamp = VeDirect.getLastUpdate();
} }

View File

@ -31,6 +31,27 @@
</div> </div>
</div> </div>
</div> </div>
<div class="btn-group me-2" role="group">
<button type="button"
class="btn btn-sm" v-tooltip :title="$t('vedirecthome.PowerLimiterState')">
<div v-if="vedirectData.PLSTATE == 0">
<BIconXCircleFill style="font-size:24px;" />
</div>
<div v-else-if="vedirectData.PLSTATE == 1">
<BIconBatteryCharging style="font-size:24px;" />
</div>
<div v-else-if="vedirectData.PLSTATE == 2">
<BIconSun style="font-size:24px;" />
</div>
<div v-else-if="vedirectData.PLSTATE == 3">
<BIconBatteryHalf style="font-size:24px;" />
</div>
<span v-if="vedirectData.PLSTATE != -1"
class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-info">
{{ vedirectData.PLLIMIT }} W
</span>
</button>
</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row flex-row flex-wrap align-items-start g-3"> <div class="row flex-row flex-wrap align-items-start g-3">
@ -178,10 +199,20 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import type { Vedirect } from '@/types/VedirectLiveDataStatus'; import type { Vedirect } from '@/types/VedirectLiveDataStatus';
import { handleResponse, authHeader, authUrl } from '@/utils/authentication'; import { handleResponse, authHeader, authUrl } from '@/utils/authentication';
import {
BIconSun,
BIconBatteryCharging,
BIconBatteryHalf,
BIconXCircleFill
} from 'bootstrap-icons-vue';
export default defineComponent({ export default defineComponent({
components: { components: {
BIconSun,
BIconBatteryCharging,
BIconBatteryHalf,
BIconXCircleFill
}, },
data() { data() {
return { return {

View File

@ -152,7 +152,8 @@
"YieldToday": "Ertrag heute", "YieldToday": "Ertrag heute",
"MaximumPowerToday": "Maximale Leistung heute", "MaximumPowerToday": "Maximale Leistung heute",
"YieldYesterday": "Ertrag gestern", "YieldYesterday": "Ertrag gestern",
"MaximumPowerYesterday": "Maximale Leistung gestern" "MaximumPowerYesterday": "Maximale Leistung gestern",
"PowerLimiterState": "Power limiter Status [aus (laden), nur die Sonne nutzen, Nutzung der Batterie]"
}, },
"eventlog": { "eventlog": {
"Start": "Begin", "Start": "Begin",

View File

@ -152,7 +152,8 @@
"YieldToday": "Yield today", "YieldToday": "Yield today",
"MaximumPowerToday": "Maximum power today", "MaximumPowerToday": "Maximum power today",
"YieldYesterday": "Yield yesterday", "YieldYesterday": "Yield yesterday",
"MaximumPowerYesterday": "Maximum power yesterday" "MaximumPowerYesterday": "Maximum power yesterday",
"PowerLimiterState": "Power limiter state [off (charging), solar passthrough, on battery]"
}, },
"eventlog": { "eventlog": {
"Start": "Start", "Start": "Start",

View File

@ -22,4 +22,6 @@ export interface Vedirect {
H21: ValueObject; H21: ValueObject;
H22: ValueObject; H22: ValueObject;
H23: ValueObject; H23: ValueObject;
PLSTATE: number;
PLLIMIT: number;
} }