Feature: First very basic support to read the grid profile

The parser is still missing and requires community support to collect data.
This commit is contained in:
Thomas Basler 2023-09-07 19:57:40 +02:00
parent 1acefd8b8c
commit 9ac6dd6e8d
20 changed files with 379 additions and 4 deletions

View File

@ -7,6 +7,7 @@
#include "WebApi_dtu.h" #include "WebApi_dtu.h"
#include "WebApi_eventlog.h" #include "WebApi_eventlog.h"
#include "WebApi_firmware.h" #include "WebApi_firmware.h"
#include "WebApi_gridprofile.h"
#include "WebApi_inverter.h" #include "WebApi_inverter.h"
#include "WebApi_limit.h" #include "WebApi_limit.h"
#include "WebApi_maintenance.h" #include "WebApi_maintenance.h"
@ -43,6 +44,7 @@ private:
WebApiDtuClass _webApiDtu; WebApiDtuClass _webApiDtu;
WebApiEventlogClass _webApiEventlog; WebApiEventlogClass _webApiEventlog;
WebApiFirmwareClass _webApiFirmware; WebApiFirmwareClass _webApiFirmware;
WebApiGridProfileClass _webApiGridprofile;
WebApiInverterClass _webApiInverter; WebApiInverterClass _webApiInverter;
WebApiLimitClass _webApiLimit; WebApiLimitClass _webApiLimit;
WebApiMaintenanceClass _webApiMaintenance; WebApiMaintenanceClass _webApiMaintenance;

View File

@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
class WebApiGridProfileClass {
public:
void init(AsyncWebServer* server);
void loop();
private:
void onGridProfileStatus(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};

View File

@ -100,6 +100,11 @@ void HoymilesClass::loop()
} }
} }
// Fetch grid profile
if (iv->Statistics()->getLastUpdate() > 0 && iv->GridProfile()->getLastUpdate() == 0) {
iv->sendGridOnProFileParaRequest();
}
if (++inverterPos >= getNumInverters()) { if (++inverterPos >= getNumInverters()) {
inverterPos = 0; inverterPos = 0;
} }

View File

@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2022 Thomas Basler and others
*/
#include "GridOnProFilePara.h"
#include "Hoymiles.h"
#include "inverters/InverterAbstract.h"
GridOnProFilePara::GridOnProFilePara(uint64_t target_address, uint64_t router_address, time_t time)
: MultiDataCommand(target_address, router_address)
{
setTime(time);
setDataType(0x02);
setTimeout(500);
}
String GridOnProFilePara::getCommandName()
{
return "GridOnProFilePara";
}
bool GridOnProFilePara::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{
// Check CRC of whole payload
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
return false;
}
// Move all fragments into target buffer
uint8_t offs = 0;
inverter->GridProfile()->beginAppendFragment();
inverter->GridProfile()->clearBuffer();
for (uint8_t i = 0; i < max_fragment_id; i++) {
inverter->GridProfile()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
offs += (fragment[i].len);
}
inverter->GridProfile()->endAppendFragment();
inverter->GridProfile()->setLastUpdate(millis());
return true;
}

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "MultiDataCommand.h"
class GridOnProFilePara : public MultiDataCommand {
public:
explicit GridOnProFilePara(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
virtual String getCommandName();
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
};

View File

@ -8,6 +8,7 @@
* AlarmDataCommand * AlarmDataCommand
* DevInfoAllCommand * DevInfoAllCommand
* DevInfoSimpleCommand * DevInfoSimpleCommand
* GridOnProFilePara
* RealTimeRunDataCommand * RealTimeRunDataCommand
* SystemConfigParaCommand * SystemConfigParaCommand
* ParaSetCommand * ParaSetCommand

View File

@ -8,6 +8,7 @@
#include "commands/AlarmDataCommand.h" #include "commands/AlarmDataCommand.h"
#include "commands/DevInfoAllCommand.h" #include "commands/DevInfoAllCommand.h"
#include "commands/DevInfoSimpleCommand.h" #include "commands/DevInfoSimpleCommand.h"
#include "commands/GridOnProFilePara.h"
#include "commands/PowerControlCommand.h" #include "commands/PowerControlCommand.h"
#include "commands/RealTimeRunDataCommand.h" #include "commands/RealTimeRunDataCommand.h"
#include "commands/SystemConfigParaCommand.h" #include "commands/SystemConfigParaCommand.h"
@ -202,4 +203,26 @@ bool HM_Abstract::resendPowerControlRequest()
return false; return false;
break; break;
} }
} }
bool HM_Abstract::sendGridOnProFileParaRequest()
{
if (!getEnablePolling()) {
return false;
}
struct tm timeinfo;
if (!getLocalTime(&timeinfo, 5)) {
return false;
}
time_t now;
time(&now);
auto cmd = _radio->prepareCommand<GridOnProFilePara>();
cmd->setTime(now);
cmd->setTargetAddress(serial());
_radio->enqueCommand(cmd);
return true;
}

View File

@ -15,6 +15,7 @@ public:
bool sendPowerControlRequest(bool turnOn); bool sendPowerControlRequest(bool turnOn);
bool sendRestartControlRequest(); bool sendRestartControlRequest();
bool resendPowerControlRequest(); bool resendPowerControlRequest();
bool sendGridOnProFileParaRequest();
private: private:
uint8_t _lastAlarmLogCnt = 0; uint8_t _lastAlarmLogCnt = 0;

View File

@ -20,6 +20,7 @@ InverterAbstract::InverterAbstract(HoymilesRadio* radio, uint64_t serial)
_alarmLogParser.reset(new AlarmLogParser()); _alarmLogParser.reset(new AlarmLogParser());
_devInfoParser.reset(new DevInfoParser()); _devInfoParser.reset(new DevInfoParser());
_gridProfileParser.reset(new GridProfileParser());
_powerCommandParser.reset(new PowerCommandParser()); _powerCommandParser.reset(new PowerCommandParser());
_statisticsParser.reset(new StatisticsParser()); _statisticsParser.reset(new StatisticsParser());
_systemConfigParaParser.reset(new SystemConfigParaParser()); _systemConfigParaParser.reset(new SystemConfigParaParser());
@ -146,6 +147,11 @@ DevInfoParser* InverterAbstract::DevInfo()
return _devInfoParser.get(); return _devInfoParser.get();
} }
GridProfileParser* InverterAbstract::GridProfile()
{
return _gridProfileParser.get();
}
PowerCommandParser* InverterAbstract::PowerCommand() PowerCommandParser* InverterAbstract::PowerCommand()
{ {
return _powerCommandParser.get(); return _powerCommandParser.get();

View File

@ -4,6 +4,7 @@
#include "../commands/ActivePowerControlCommand.h" #include "../commands/ActivePowerControlCommand.h"
#include "../parser/AlarmLogParser.h" #include "../parser/AlarmLogParser.h"
#include "../parser/DevInfoParser.h" #include "../parser/DevInfoParser.h"
#include "../parser/GridProfileParser.h"
#include "../parser/PowerCommandParser.h" #include "../parser/PowerCommandParser.h"
#include "../parser/StatisticsParser.h" #include "../parser/StatisticsParser.h"
#include "../parser/SystemConfigParaParser.h" #include "../parser/SystemConfigParaParser.h"
@ -71,11 +72,13 @@ public:
virtual bool sendRestartControlRequest() = 0; virtual bool sendRestartControlRequest() = 0;
virtual bool resendPowerControlRequest() = 0; virtual bool resendPowerControlRequest() = 0;
virtual bool sendChangeChannelRequest(); virtual bool sendChangeChannelRequest();
virtual bool sendGridOnProFileParaRequest() = 0;
HoymilesRadio* getRadio(); HoymilesRadio* getRadio();
AlarmLogParser* EventLog(); AlarmLogParser* EventLog();
DevInfoParser* DevInfo(); DevInfoParser* DevInfo();
GridProfileParser* GridProfile();
PowerCommandParser* PowerCommand(); PowerCommandParser* PowerCommand();
StatisticsParser* Statistics(); StatisticsParser* Statistics();
SystemConfigParaParser* SystemConfigPara(); SystemConfigParaParser* SystemConfigPara();
@ -102,6 +105,7 @@ private:
std::unique_ptr<AlarmLogParser> _alarmLogParser; std::unique_ptr<AlarmLogParser> _alarmLogParser;
std::unique_ptr<DevInfoParser> _devInfoParser; std::unique_ptr<DevInfoParser> _devInfoParser;
std::unique_ptr<GridProfileParser> _gridProfileParser;
std::unique_ptr<PowerCommandParser> _powerCommandParser; std::unique_ptr<PowerCommandParser> _powerCommandParser;
std::unique_ptr<StatisticsParser> _statisticsParser; std::unique_ptr<StatisticsParser> _statisticsParser;
std::unique_ptr<SystemConfigParaParser> _systemConfigParaParser; std::unique_ptr<SystemConfigParaParser> _systemConfigParaParser;

View File

@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2022 Thomas Basler and others
*/
#include "GridProfileParser.h"
#include "../Hoymiles.h"
#include <cstring>
#define HOY_SEMAPHORE_TAKE() \
do { \
} while (xSemaphoreTake(_xSemaphore, portMAX_DELAY) != pdPASS)
#define HOY_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
GridProfileParser::GridProfileParser()
: Parser()
{
_xSemaphore = xSemaphoreCreateMutex();
HOY_SEMAPHORE_GIVE(); // release before first use
clearBuffer();
}
void GridProfileParser::clearBuffer()
{
memset(_payloadGridProfile, 0, GRID_PROFILE_SIZE);
_gridProfileLength = 0;
}
void GridProfileParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > GRID_PROFILE_SIZE) {
Hoymiles.getMessageOutput()->printf("FATAL: (%s, %d) grid profile packet too large for buffer\r\n", __FILE__, __LINE__);
return;
}
memcpy(&_payloadGridProfile[offset], payload, len);
_gridProfileLength += len;
}
void GridProfileParser::beginAppendFragment()
{
HOY_SEMAPHORE_TAKE();
}
void GridProfileParser::endAppendFragment()
{
HOY_SEMAPHORE_GIVE();
}
std::vector<uint8_t> GridProfileParser::getRawData()
{
std::vector<uint8_t> ret;
HOY_SEMAPHORE_TAKE();
for (uint8_t i = 0; i < GRID_PROFILE_SIZE; i++) {
ret.push_back(_payloadGridProfile[i]);
}
HOY_SEMAPHORE_GIVE();
return ret;
}

View File

@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Parser.h"
#include <Arduino.h>
#define GRID_PROFILE_SIZE 141
class GridProfileParser : public Parser {
public:
GridProfileParser();
void clearBuffer();
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
void beginAppendFragment();
void endAppendFragment();
std::vector<uint8_t> getRawData();
private:
uint8_t _payloadGridProfile[GRID_PROFILE_SIZE] = {};
uint8_t _gridProfileLength = 0;
SemaphoreHandle_t _xSemaphore;
};

View File

@ -23,6 +23,7 @@ void WebApiClass::init()
_webApiDtu.init(&_server); _webApiDtu.init(&_server);
_webApiEventlog.init(&_server); _webApiEventlog.init(&_server);
_webApiFirmware.init(&_server); _webApiFirmware.init(&_server);
_webApiGridprofile.init(&_server);
_webApiInverter.init(&_server); _webApiInverter.init(&_server);
_webApiLimit.init(&_server); _webApiLimit.init(&_server);
_webApiMaintenance.init(&_server); _webApiMaintenance.init(&_server);
@ -48,6 +49,7 @@ void WebApiClass::loop()
_webApiDtu.loop(); _webApiDtu.loop();
_webApiEventlog.loop(); _webApiEventlog.loop();
_webApiFirmware.loop(); _webApiFirmware.loop();
_webApiGridprofile.loop();
_webApiInverter.loop(); _webApiInverter.loop();
_webApiLimit.loop(); _webApiLimit.loop();
_webApiMaintenance.loop(); _webApiMaintenance.loop();

View File

@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2022 Thomas Basler and others
*/
#include "WebApi_gridprofile.h"
#include "WebApi.h"
#include <AsyncJson.h>
#include <Hoymiles.h>
void WebApiGridProfileClass::init(AsyncWebServer* server)
{
using std::placeholders::_1;
_server = server;
_server->on("/api/gridprofile/status", HTTP_GET, std::bind(&WebApiGridProfileClass::onGridProfileStatus, this, _1));
}
void WebApiGridProfileClass::loop()
{
}
void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
{
if (!WebApi.checkCredentialsReadonly(request)) {
return;
}
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096);
JsonObject root = response->getRoot();
uint64_t serial = 0;
if (request->hasParam("inv")) {
String s = request->getParam("inv")->value();
serial = strtoll(s.c_str(), NULL, 16);
}
auto inv = Hoymiles.getInverterBySerial(serial);
if (inv != nullptr) {
auto raw = root.createNestedArray("raw");
auto data = inv->GridProfile()->getRawData();
copyArray(&data[0], data.size(), raw);
}
response->setLength();
request->send(response);
}

View File

@ -0,0 +1,50 @@
<template>
<BootstrapAlert :show="!hasValidData">
<h4 class="alert-heading">
<BIconInfoSquare class="fs-2" />&nbsp;{{ $t('gridprofile.NoInfo') }}
</h4>{{ $t('gridprofile.NoInfoLong') }}
</BootstrapAlert>
<template v-if="hasValidData">
<BootstrapAlert :show="true" variant="danger">
<h4 class="info-heading">
<BIconInfoSquare class="fs-2" />&nbsp;{{ $t('gridprofile.GridprofileSupport') }}
</h4><div v-html="$t('gridprofile.GridprofileSupportLong')"></div>
</BootstrapAlert>
<samp >
{{ rawContent() }}
</samp>
</template>
</template>
<script lang="ts">
import BootstrapAlert from '@/components/BootstrapAlert.vue';
import type { GridProfileStatus } from "@/types/GridProfileStatus";
import { BIconInfoSquare } from 'bootstrap-icons-vue';
import { defineComponent, type PropType } from 'vue';
export default defineComponent({
components: {
BootstrapAlert,
BIconInfoSquare,
},
props: {
gridProfileList: { type: Object as PropType<GridProfileStatus>, required: true },
},
computed: {
rawContent() {
return () => {
return this.gridProfileList.raw.map(function (x) {
let y = x.toString(16); // to hex
y = ("00" + y).substr(-2); // zero-pad to 2-digits
return y
}).join(' ');
}
},
hasValidData() {
return this.gridProfileList.raw.reduce((sum, x) => sum + x, 0) > 0;
},
},
});
</script>

View File

@ -126,7 +126,9 @@
"Failure": "Fehlgeschlagen", "Failure": "Fehlgeschlagen",
"Pending": "Ausstehend", "Pending": "Ausstehend",
"Ok": "Ok", "Ok": "Ok",
"Unknown": "Unbekannt" "Unknown": "Unbekannt",
"ShowGridProfile": "Zeige Grid Profil",
"GridProfile": "Grid Profil"
}, },
"eventlog": { "eventlog": {
"Start": "Begin", "Start": "Begin",
@ -149,6 +151,12 @@
"HardwarePartNumber": "Hardware-Teilenummer", "HardwarePartNumber": "Hardware-Teilenummer",
"HardwareVersion": "Hardware-Version" "HardwareVersion": "Hardware-Version"
}, },
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
"NoInfoLong": "@:devinfo.NoInfoLong",
"GridprofileSupport": "Unterstütze die Entwicklung",
"GridprofileSupportLong": "Weitere Informationen sind <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">hier</a> zu finden."
},
"systeminfo": { "systeminfo": {
"SystemInfo": "System Informationen", "SystemInfo": "System Informationen",
"VersionError": "Fehler beim Abrufen von Versionsinformationen", "VersionError": "Fehler beim Abrufen von Versionsinformationen",

View File

@ -126,7 +126,9 @@
"Failure": "Failure", "Failure": "Failure",
"Pending": "Pending", "Pending": "Pending",
"Ok": "Ok", "Ok": "Ok",
"Unknown": "Unknown" "Unknown": "Unknown",
"ShowGridProfile": "Show Grid Profile",
"GridProfile": "Grid Profile"
}, },
"eventlog": { "eventlog": {
"Start": "Start", "Start": "Start",
@ -149,6 +151,12 @@
"HardwarePartNumber": "Hardware Part Number", "HardwarePartNumber": "Hardware Part Number",
"HardwareVersion": "Hardware Version" "HardwareVersion": "Hardware Version"
}, },
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
"NoInfoLong": "@:devinfo.NoInfoLong",
"GridprofileSupport": "Support the development",
"GridprofileSupportLong": "Please see <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">here</a> for further information."
},
"systeminfo": { "systeminfo": {
"SystemInfo": "System Info", "SystemInfo": "System Info",
"VersionError": "Error fetching version information", "VersionError": "Error fetching version information",

View File

@ -126,7 +126,9 @@
"Failure": "Échec", "Failure": "Échec",
"Pending": "En attente", "Pending": "En attente",
"Ok": "OK", "Ok": "OK",
"Unknown": "Inconnu" "Unknown": "Inconnu",
"ShowGridProfile": "Show Grid Profile",
"GridProfile": "Grid Profile"
}, },
"eventlog": { "eventlog": {
"Start": "Départ", "Start": "Départ",
@ -149,6 +151,12 @@
"HardwarePartNumber": "Numéro d'article matériel", "HardwarePartNumber": "Numéro d'article matériel",
"HardwareVersion": "Version du matériel" "HardwareVersion": "Version du matériel"
}, },
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
"NoInfoLong": "@:devinfo.NoInfoLong",
"GridprofileSupport": "Support the development",
"GridprofileSupportLong": "Please see <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">here</a> for further information."
},
"systeminfo": { "systeminfo": {
"SystemInfo": "Informations sur le système", "SystemInfo": "Informations sur le système",
"VersionError": "Erreur de récupération des informations de version", "VersionError": "Erreur de récupération des informations de version",

View File

@ -0,0 +1,3 @@
export interface GridProfileStatus {
raw: Array<number>;
}

View File

@ -78,6 +78,14 @@
</button> </button>
</div> </div>
<div class="btn-group me-2" role="group">
<button type="button" class="btn btn-sm btn-info"
@click="onShowGridProfile(inverter.serial)" v-tooltip :title="$t('home.ShowGridProfile')">
<BIconOutlet style="font-size:24px;" />
</button>
</div>
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button v-if="inverter.events >= 0" type="button" <button v-if="inverter.events >= 0" type="button"
class="btn btn-sm btn-secondary position-relative" class="btn btn-sm btn-secondary position-relative"
@ -167,6 +175,31 @@
</div> </div>
</div> </div>
<div class="modal" id="gridProfileView" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ $t('home.GridProfile') }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center" v-if="gridProfileLoading">
<div class="spinner-border" role="status">
<span class="visually-hidden">{{ $t('home.Loading') }}</span>
</div>
</div>
<GridProfile v-if="!gridProfileLoading" :gridProfileList="gridProfileList" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @click="onHideGridProfile"
data-bs-dismiss="modal">{{ $t('home.Close') }}</button>
</div>
</div>
</div>
</div>
<div class="modal" id="limitSettingView" ref="limitSettingView" tabindex="-1"> <div class="modal" id="limitSettingView" ref="limitSettingView" tabindex="-1">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
@ -321,11 +354,13 @@ import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from '@/components/BootstrapAlert.vue'; import BootstrapAlert from '@/components/BootstrapAlert.vue';
import DevInfo from '@/components/DevInfo.vue'; import DevInfo from '@/components/DevInfo.vue';
import EventLog from '@/components/EventLog.vue'; import EventLog from '@/components/EventLog.vue';
import GridProfile from '@/components/GridProfile.vue';
import HintView from '@/components/HintView.vue'; import HintView from '@/components/HintView.vue';
import InverterChannelInfo from "@/components/InverterChannelInfo.vue"; import InverterChannelInfo from "@/components/InverterChannelInfo.vue";
import InverterTotalInfo from '@/components/InverterTotalInfo.vue'; import InverterTotalInfo from '@/components/InverterTotalInfo.vue';
import type { DevInfoStatus } from '@/types/DevInfoStatus'; import type { DevInfoStatus } from '@/types/DevInfoStatus';
import type { EventlogItems } from '@/types/EventlogStatus'; import type { EventlogItems } from '@/types/EventlogStatus';
import type { GridProfileStatus } from '@/types/GridProfileStatus';
import type { LimitConfig } from '@/types/LimitConfig'; import type { LimitConfig } from '@/types/LimitConfig';
import type { LimitStatus } from '@/types/LimitStatus'; import type { LimitStatus } from '@/types/LimitStatus';
import type { Inverter, LiveData } from '@/types/LiveDataStatus'; import type { Inverter, LiveData } from '@/types/LiveDataStatus';
@ -337,6 +372,7 @@ import {
BIconCpu, BIconCpu,
BIconExclamationCircleFill, BIconExclamationCircleFill,
BIconJournalText, BIconJournalText,
BIconOutlet,
BIconPower, BIconPower,
BIconSpeedometer, BIconSpeedometer,
BIconToggleOff, BIconToggleOff,
@ -351,6 +387,7 @@ export default defineComponent({
BootstrapAlert, BootstrapAlert,
DevInfo, DevInfo,
EventLog, EventLog,
GridProfile,
HintView, HintView,
InverterChannelInfo, InverterChannelInfo,
InverterTotalInfo, InverterTotalInfo,
@ -359,6 +396,7 @@ export default defineComponent({
BIconCpu, BIconCpu,
BIconExclamationCircleFill, BIconExclamationCircleFill,
BIconJournalText, BIconJournalText,
BIconOutlet,
BIconPower, BIconPower,
BIconSpeedometer, BIconSpeedometer,
BIconToggleOff, BIconToggleOff,
@ -381,6 +419,9 @@ export default defineComponent({
devInfoView: {} as bootstrap.Modal, devInfoView: {} as bootstrap.Modal,
devInfoList: {} as DevInfoStatus, devInfoList: {} as DevInfoStatus,
devInfoLoading: true, devInfoLoading: true,
gridProfileView: {} as bootstrap.Modal,
gridProfileList: {} as GridProfileStatus,
gridProfileLoading: true,
limitSettingView: {} as bootstrap.Modal, limitSettingView: {} as bootstrap.Modal,
limitSettingLoading: true, limitSettingLoading: true,
@ -421,6 +462,7 @@ export default defineComponent({
mounted() { mounted() {
this.eventLogView = new bootstrap.Modal('#eventView'); this.eventLogView = new bootstrap.Modal('#eventView');
this.devInfoView = new bootstrap.Modal('#devInfoView'); this.devInfoView = new bootstrap.Modal('#devInfoView');
this.gridProfileView = new bootstrap.Modal('#gridProfileView');
this.limitSettingView = new bootstrap.Modal('#limitSettingView'); this.limitSettingView = new bootstrap.Modal('#limitSettingView');
this.powerSettingView = new bootstrap.Modal('#powerSettingView'); this.powerSettingView = new bootstrap.Modal('#powerSettingView');
@ -562,6 +604,20 @@ export default defineComponent({
this.devInfoView.show(); this.devInfoView.show();
}, },
onHideGridProfile() {
this.devInfoView.hide();
},
onShowGridProfile(serial: number) {
this.gridProfileLoading = true;
fetch("/api/gridprofile/status?inv=" + serial, { headers: authHeader() })
.then((response) => handleResponse(response, this.$emitter, this.$router))
.then((data) => {
this.gridProfileList = data;
this.gridProfileLoading = false;
});
this.gridProfileView.show();
},
onHideLimitSettings() { onHideLimitSettings() {
this.showAlertLimit = false; this.showAlertLimit = false;
}, },