BREAKING CHANGE: Structure WebAPI /api/livedata/status changed
The different inverter data are now in a subobject called "inverters". This is required to extend the API by other data then the inverter values
This commit is contained in:
parent
f854cdff03
commit
69b675bc64
@ -13,7 +13,7 @@ public:
|
||||
|
||||
private:
|
||||
void generateJsonResponse(JsonVariant& root);
|
||||
void addField(JsonVariant& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, uint8_t channel, uint8_t fieldId, String topic = "");
|
||||
void addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, uint8_t channel, uint8_t fieldId, String topic = "");
|
||||
void onLivedataStatus(AsyncWebServerRequest* request);
|
||||
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||
|
||||
|
||||
@ -73,48 +73,51 @@ void WebApiWsLiveClass::loop()
|
||||
|
||||
void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
||||
{
|
||||
JsonArray invArray = root.createNestedArray("inverters");
|
||||
// Loop all inverters
|
||||
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
||||
auto inv = Hoymiles.getInverterByPos(i);
|
||||
|
||||
root[i][F("serial")] = inv->serialString();
|
||||
root[i][F("name")] = inv->name();
|
||||
root[i][F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000;
|
||||
root[i][F("reachable")] = inv->isReachable();
|
||||
root[i][F("producing")] = inv->isProducing();
|
||||
root[i][F("limit_relative")] = inv->SystemConfigPara()->getLimitPercent();
|
||||
JsonObject invObject = invArray.createNestedObject();
|
||||
|
||||
invObject[F("serial")] = inv->serialString();
|
||||
invObject[F("name")] = inv->name();
|
||||
invObject[F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000;
|
||||
invObject[F("reachable")] = inv->isReachable();
|
||||
invObject[F("producing")] = inv->isProducing();
|
||||
invObject[F("limit_relative")] = inv->SystemConfigPara()->getLimitPercent();
|
||||
if (inv->DevInfo()->getMaxPower() > 0) {
|
||||
root[i][F("limit_absolute")] = inv->SystemConfigPara()->getLimitPercent() * inv->DevInfo()->getMaxPower() / 100.0;
|
||||
invObject[F("limit_absolute")] = inv->SystemConfigPara()->getLimitPercent() * inv->DevInfo()->getMaxPower() / 100.0;
|
||||
} else {
|
||||
root[i][F("limit_absolute")] = -1;
|
||||
invObject[F("limit_absolute")] = -1;
|
||||
}
|
||||
|
||||
// Loop all channels
|
||||
for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) {
|
||||
addField(root, i, inv, c, FLD_PAC);
|
||||
addField(root, i, inv, c, FLD_UAC);
|
||||
addField(root, i, inv, c, FLD_IAC);
|
||||
addField(invObject, i, inv, c, FLD_PAC);
|
||||
addField(invObject, i, inv, c, FLD_UAC);
|
||||
addField(invObject, i, inv, c, FLD_IAC);
|
||||
if (c == 0) {
|
||||
addField(root, i, inv, c, FLD_PDC, F("Power DC"));
|
||||
addField(invObject, i, inv, c, FLD_PDC, F("Power DC"));
|
||||
} else {
|
||||
addField(root, i, inv, c, FLD_PDC);
|
||||
addField(invObject, i, inv, c, FLD_PDC);
|
||||
}
|
||||
addField(root, i, inv, c, FLD_UDC);
|
||||
addField(root, i, inv, c, FLD_IDC);
|
||||
addField(root, i, inv, c, FLD_YD);
|
||||
addField(root, i, inv, c, FLD_YT);
|
||||
addField(root, i, inv, c, FLD_F);
|
||||
addField(root, i, inv, c, FLD_T);
|
||||
addField(root, i, inv, c, FLD_PF);
|
||||
addField(root, i, inv, c, FLD_PRA);
|
||||
addField(root, i, inv, c, FLD_EFF);
|
||||
addField(root, i, inv, c, FLD_IRR);
|
||||
addField(invObject, i, inv, c, FLD_UDC);
|
||||
addField(invObject, i, inv, c, FLD_IDC);
|
||||
addField(invObject, i, inv, c, FLD_YD);
|
||||
addField(invObject, i, inv, c, FLD_YT);
|
||||
addField(invObject, i, inv, c, FLD_F);
|
||||
addField(invObject, i, inv, c, FLD_T);
|
||||
addField(invObject, i, inv, c, FLD_PF);
|
||||
addField(invObject, i, inv, c, FLD_PRA);
|
||||
addField(invObject, i, inv, c, FLD_EFF);
|
||||
addField(invObject, i, inv, c, FLD_IRR);
|
||||
}
|
||||
|
||||
if (inv->Statistics()->hasChannelFieldValue(CH0, FLD_EVT_LOG)) {
|
||||
root[i][F("events")] = inv->EventLog()->getEntryCount();
|
||||
invObject[F("events")] = inv->EventLog()->getEntryCount();
|
||||
} else {
|
||||
root[i][F("events")] = -1;
|
||||
invObject[F("events")] = -1;
|
||||
}
|
||||
|
||||
if (inv->Statistics()->getLastUpdate() > _newestInverterTimestamp) {
|
||||
@ -123,7 +126,7 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
||||
}
|
||||
}
|
||||
|
||||
void WebApiWsLiveClass::addField(JsonVariant& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, uint8_t channel, uint8_t fieldId, String topic)
|
||||
void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, uint8_t channel, uint8_t fieldId, String topic)
|
||||
{
|
||||
if (inv->Statistics()->hasChannelFieldValue(channel, fieldId)) {
|
||||
String chanName;
|
||||
@ -132,9 +135,9 @@ void WebApiWsLiveClass::addField(JsonVariant& root, uint8_t idx, std::shared_ptr
|
||||
} else {
|
||||
chanName = topic;
|
||||
}
|
||||
root[idx][String(channel)][chanName]["v"] = inv->Statistics()->getChannelFieldValue(channel, fieldId);
|
||||
root[idx][String(channel)][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(channel, fieldId);
|
||||
root[idx][String(channel)][chanName]["d"] = inv->Statistics()->getChannelFieldDigits(channel, fieldId);
|
||||
root[String(channel)][chanName]["v"] = inv->Statistics()->getChannelFieldValue(channel, fieldId);
|
||||
root[String(channel)][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(channel, fieldId);
|
||||
root[String(channel)][chanName]["d"] = inv->Statistics()->getChannelFieldDigits(channel, fieldId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,8 +156,8 @@ void WebApiWsLiveClass::onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketC
|
||||
|
||||
void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
||||
{
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(true, 40960U);
|
||||
JsonVariant root = response->getRoot().as<JsonVariant>();
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 40960U);
|
||||
JsonVariant root = response->getRoot();
|
||||
|
||||
generateJsonResponse(root);
|
||||
|
||||
|
||||
@ -31,4 +31,6 @@ export interface Inverter {
|
||||
[key: number]: InverterStatistics,
|
||||
};
|
||||
|
||||
export interface Inverters extends Array<Inverter>{};
|
||||
export interface LiveData {
|
||||
inverters: Inverter[],
|
||||
}
|
||||
@ -332,7 +332,7 @@ import BootstrapAlert from '@/components/BootstrapAlert.vue';
|
||||
import InverterChannelInfo from "@/components/InverterChannelInfo.vue";
|
||||
import type { DevInfoStatus } from '@/types/DevInfoStatus';
|
||||
import type { EventlogItems } from '@/types/EventlogStatus';
|
||||
import type { Inverters } from '@/types/LiveDataStatus';
|
||||
import type { LiveData, Inverter } from '@/types/LiveDataStatus';
|
||||
import type { LimitStatus } from '@/types/LimitStatus';
|
||||
import type { LimitConfig } from '@/types/LimitConfig';
|
||||
import { formatNumber } from '@/utils';
|
||||
@ -361,7 +361,7 @@ export default defineComponent({
|
||||
heartInterval: 0,
|
||||
dataAgeInterval: 0,
|
||||
dataLoading: true,
|
||||
inverterData: [] as Inverters,
|
||||
liveData: {} as LiveData,
|
||||
isFirstFetchAfterConnect: true,
|
||||
eventLogView: {} as bootstrap.Modal,
|
||||
eventLogList: {} as EventlogItems,
|
||||
@ -435,6 +435,9 @@ export default defineComponent({
|
||||
},
|
||||
currentLimitRelative(): string {
|
||||
return formatNumber(this.currentLimitList.limit_relative, 2);
|
||||
},
|
||||
inverterData(): Inverter[] {
|
||||
return this.liveData.inverters;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -444,7 +447,7 @@ export default defineComponent({
|
||||
fetch("/api/livedata/status")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
this.inverterData = data;
|
||||
this.liveData = data;
|
||||
this.dataLoading = false;
|
||||
});
|
||||
},
|
||||
@ -459,7 +462,7 @@ export default defineComponent({
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
console.log(event);
|
||||
this.inverterData = JSON.parse(event.data);
|
||||
this.liveData = JSON.parse(event.data);
|
||||
this.dataLoading = false;
|
||||
this.heartCheck(); // Reset heartbeat detection
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user