mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-11 07:56:39 +02:00
* added option for no powerlimit (setup)
* moved function showLiveData to web.cpp * improved debug messages * cleaned some code
This commit is contained in:
parent
fec8758de7
commit
ae968d618a
7 changed files with 152 additions and 191 deletions
|
@ -115,23 +115,23 @@ void app::loop(void) {
|
||||||
if(NULL != iv && p->packet[0] == (TX_REQ_DEVCONTROL + 0x80)) { // response from dev control command
|
if(NULL != iv && p->packet[0] == (TX_REQ_DEVCONTROL + 0x80)) { // response from dev control command
|
||||||
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
|
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
|
||||||
iv->devControlRequest = false;
|
iv->devControlRequest = false;
|
||||||
switch (p->packet[12]){
|
switch (p->packet[12]) {
|
||||||
case ActivePowerContr:
|
case ActivePowerContr:
|
||||||
if (iv->devControlCmd >= ActivePowerContr && iv->devControlCmd <= PFSet){ // ok inverter accepted the set point copy it to dtu eeprom
|
if (iv->devControlCmd >= ActivePowerContr && iv->devControlCmd <= PFSet) { // ok inverter accepted the set point copy it to dtu eeprom
|
||||||
if ((iv->powerLimit[1] & 0xff00) >0){ // User want to have it persistent
|
if ((iv->powerLimit[1] & 0xff00) > 0) { // User want to have it persistent
|
||||||
mEep->write(ADDR_INV_PWR_LIM + iv->id * 2,iv->powerLimit[0]);
|
mEep->write(ADDR_INV_PWR_LIM + iv->id * 2, iv->powerLimit[0]);
|
||||||
mEep->write(ADDR_INV_PWR_LIM_CON + iv->id * 2,iv->powerLimit[1]);
|
mEep->write(ADDR_INV_PWR_LIM_CON + iv->id * 2, iv->powerLimit[1]);
|
||||||
updateCrc();
|
updateCrc();
|
||||||
mEep->commit();
|
mEep->commit();
|
||||||
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]) + F(", written to dtu eeprom"));
|
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]) + F(", written to dtu eeprom"));
|
||||||
} else {
|
} else
|
||||||
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
|
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
|
||||||
}
|
|
||||||
iv->devControlCmd = Init;
|
iv->devControlCmd = Init;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (iv->devControlCmd == ActivePowerContr){
|
if (iv->devControlCmd == ActivePowerContr) {
|
||||||
//case inverter did not accept the sent limit; set back to last stored limit
|
//case inverter did not accept the sent limit; set back to last stored limit
|
||||||
mEep->read(ADDR_INV_PWR_LIM + iv->id * 2, (uint16_t *)&(iv->powerLimit[0]));
|
mEep->read(ADDR_INV_PWR_LIM + iv->id * 2, (uint16_t *)&(iv->powerLimit[0]));
|
||||||
mEep->read(ADDR_INV_PWR_LIM_CON + iv->id * 2, (uint16_t *)&(iv->powerLimit[1]));
|
mEep->read(ADDR_INV_PWR_LIM_CON + iv->id * 2, (uint16_t *)&(iv->powerLimit[1]));
|
||||||
|
@ -160,22 +160,6 @@ void app::loop(void) {
|
||||||
if((++mMqttTicker >= mMqttInterval) && (mMqttInterval != 0xffff) && mMqttActive) {
|
if((++mMqttTicker >= mMqttInterval) && (mMqttInterval != 0xffff) && mMqttActive) {
|
||||||
mMqttTicker = 0;
|
mMqttTicker = 0;
|
||||||
mMqtt.isConnected(true); // really needed? See comment from HorstG-57 #176
|
mMqtt.isConnected(true); // really needed? See comment from HorstG-57 #176
|
||||||
/*
|
|
||||||
char topic[30], val[10];
|
|
||||||
for(uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
|
||||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
|
||||||
if(NULL != iv) {
|
|
||||||
if(iv->isAvailable(mTimestamp)) {
|
|
||||||
for(uint8_t i = 0; i < iv->listLen; i++) {
|
|
||||||
snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, fields[iv->assign[i].fieldId]);
|
|
||||||
snprintf(val, 10, "%.3f", iv->getValue(i));
|
|
||||||
mMqtt.sendMsg(topic, val);
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
char val[10];
|
char val[10];
|
||||||
snprintf(val, 10, "%ld", millis()/1000);
|
snprintf(val, 10, "%ld", millis()/1000);
|
||||||
|
|
||||||
|
@ -256,12 +240,12 @@ void app::loop(void) {
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
if(mConfig.serialDebug)
|
if(mConfig.serialDebug)
|
||||||
DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()) );
|
DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()));
|
||||||
DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX));
|
DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX));
|
||||||
if(iv->devControlRequest && iv->powerLimit[0] > 0){ // prevent to "switch off"
|
if(iv->devControlRequest && (iv->powerLimit[0] > 0) && (NoPowerLimit != iv->powerLimit[1])) { // prevent to "switch off"
|
||||||
if(mConfig.serialDebug)
|
if(mConfig.serialDebug)
|
||||||
DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
|
DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
|
||||||
mSys->Radio.sendControlPacket(iv->radioId.u64,iv->devControlCmd ,iv->powerLimit);
|
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd ,iv->powerLimit);
|
||||||
iv->enqueCommand<InfoCommand>(SystemConfigPara);
|
iv->enqueCommand<InfoCommand>(SystemConfigPara);
|
||||||
} else {
|
} else {
|
||||||
mSys->Radio.sendTimePacket(iv->radioId.u64,iv->getQueuedCmd(), mPayload[iv->id].ts,iv->alarmMesIndex);
|
mSys->Radio.sendTimePacket(iv->radioId.u64,iv->getQueuedCmd(), mPayload[iv->id].ts,iv->alarmMesIndex);
|
||||||
|
@ -516,9 +500,10 @@ String app::getStatistics(void) {
|
||||||
Inverter<> *iv;
|
Inverter<> *iv;
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||||
iv = mSys->getInverterByPos(i);
|
iv = mSys->getInverterByPos(i);
|
||||||
|
content += F("Inverter #") + String(i) + F(": ");
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
bool avail = true;
|
bool avail = true;
|
||||||
content += F("Inverter '") + String(iv->name) + F(" (FW-Version: ") + String(iv->fwVersion) +F(")") + F("' is ");
|
content += String(iv->name) + F(" (v") + String(iv->fwVersion) +F(")") + F(" is ");
|
||||||
if(!iv->isAvailable(mTimestamp)) {
|
if(!iv->isAvailable(mTimestamp)) {
|
||||||
content += F("not ");
|
content += F("not ");
|
||||||
avail = false;
|
avail = false;
|
||||||
|
@ -533,9 +518,8 @@ String app::getStatistics(void) {
|
||||||
content += F("-> last successful transmission: ") + getDateTimeStr(iv->getLastTs()) + "\n";
|
content += F("-> last successful transmission: ") + getDateTimeStr(iv->getLastTs()) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
content += F("Inverter ") + String(i) + F(" not (correctly) configured\n");
|
content += F("n/a\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mSys->Radio.isChipConnected())
|
if(!mSys->Radio.isChipConnected())
|
||||||
|
@ -556,113 +540,6 @@ String app::getStatistics(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
String app::getLiveData(void)
|
|
||||||
{
|
|
||||||
String modHtml;
|
|
||||||
for (uint8_t id = 0; id < mSys->getNumInverters(); id++)
|
|
||||||
{
|
|
||||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
|
||||||
if (NULL != iv)
|
|
||||||
{
|
|
||||||
#ifdef LIVEDATA_VISUALIZED
|
|
||||||
uint8_t modNum, pos;
|
|
||||||
switch (iv->type)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case INV_TYPE_1CH:
|
|
||||||
modNum = 1;
|
|
||||||
break;
|
|
||||||
case INV_TYPE_2CH:
|
|
||||||
modNum = 2;
|
|
||||||
break;
|
|
||||||
case INV_TYPE_4CH:
|
|
||||||
modNum = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
modHtml += F("<div class=\"iv\">"
|
|
||||||
"<div class=\"ch-iv\"><span class=\"head\">") +
|
|
||||||
String(iv->name) + F(" Limit ") + String(iv->actPowerLimit)
|
|
||||||
+ F("% | last Alarm: ") + iv->lastAlarmMsg + F("</span>");
|
|
||||||
|
|
||||||
uint8_t list[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PCT, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_PRA, FLD_ALARM_MES_ID};
|
|
||||||
|
|
||||||
for (uint8_t fld = 0; fld < 11; fld++)
|
|
||||||
{
|
|
||||||
pos = (iv->getPosByChFld(CH0, list[fld]));
|
|
||||||
if (0xff != pos)
|
|
||||||
{
|
|
||||||
modHtml += F("<div class=\"subgrp\">");
|
|
||||||
modHtml += F("<span class=\"value\">") + String(iv->getValue(pos));
|
|
||||||
modHtml += F("<span class=\"unit\">") + String(iv->getUnit(pos)) + F("</span></span>");
|
|
||||||
modHtml += F("<span class=\"info\">") + String(iv->getFieldName(pos)) + F("</span>");
|
|
||||||
modHtml += F("</div>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
modHtml += "</div>";
|
|
||||||
|
|
||||||
for (uint8_t ch = 1; ch <= modNum; ch++)
|
|
||||||
{
|
|
||||||
modHtml += F("<div class=\"ch\"><span class=\"head\">");
|
|
||||||
if (iv->chName[ch - 1][0] == 0)
|
|
||||||
modHtml += F("CHANNEL ") + String(ch);
|
|
||||||
else
|
|
||||||
modHtml += String(iv->chName[ch - 1]);
|
|
||||||
modHtml += F("</span>");
|
|
||||||
for (uint8_t j = 0; j < 6; j++)
|
|
||||||
{
|
|
||||||
switch (j)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_UDC));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_IDC));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_PDC));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_YD));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_YT));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
pos = (iv->getPosByChFld(ch, FLD_IRR));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (0xff != pos)
|
|
||||||
{
|
|
||||||
modHtml += F("<span class=\"value\">") + String(iv->getValue(pos));
|
|
||||||
modHtml += F("<span class=\"unit\">") + String(iv->getUnit(pos)) + F("</span></span>");
|
|
||||||
modHtml += F("<span class=\"info\">") + String(iv->getFieldName(pos)) + F("</span>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
modHtml += "</div>";
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
modHtml += F("<div class=\"ts\">Last received data requested at: ") + getDateTimeStr(iv->ts) + F("</div>");
|
|
||||||
modHtml += F("</div>");
|
|
||||||
#else
|
|
||||||
// dump all data to web frontend
|
|
||||||
modHtml = F("<pre>");
|
|
||||||
char topic[30], val[10];
|
|
||||||
for (uint8_t i = 0; i < iv->listLen; i++)
|
|
||||||
{
|
|
||||||
snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, iv->getFieldName(i));
|
|
||||||
snprintf(val, 10, "%.3f %s", iv->getValue(i), iv->getUnit(i));
|
|
||||||
modHtml += String(topic) + ": " + String(val) + "\n";
|
|
||||||
}
|
|
||||||
modHtml += F("</pre>");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return modHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
String app::getJson(void) {
|
String app::getJson(void) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("app::showJson"));
|
DPRINTLN(DBG_VERBOSE, F("app::showJson"));
|
||||||
|
@ -879,11 +756,16 @@ void app::loadEEpconfig(void) {
|
||||||
// it is "doppelt-gemoppelt" because the inverter shall remember the setting if the dtu makes a power cycle / reboot
|
// it is "doppelt-gemoppelt" because the inverter shall remember the setting if the dtu makes a power cycle / reboot
|
||||||
if (iv->powerLimit[0] != 0xffff) {
|
if (iv->powerLimit[0] != 0xffff) {
|
||||||
iv->devControlCmd = ActivePowerContr; // set active power limit
|
iv->devControlCmd = ActivePowerContr; // set active power limit
|
||||||
if (iv->powerLimit[1] & 0x0001){
|
DPRINT(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX));
|
||||||
DPRINTLN(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX) + ", Power Limit: " + String(iv->powerLimit[0]) + " in %");
|
if(iv->powerLimit[1] != NoPowerLimit) {
|
||||||
} else {
|
DBGPRINT(F(", Power Limit: ") + String(iv->powerLimit[0]));
|
||||||
DPRINTLN(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX) + ", Power Limit: " + String(iv->powerLimit[0]) + " in Watt");
|
if ((iv->powerLimit[1] & 0x0001) == 0x0001)
|
||||||
|
DBGPRINTLN(F(" in %"));
|
||||||
|
else
|
||||||
|
DBGPRINTLN(F(" in Watt"));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DBGPRINTLN(F(" "));
|
||||||
}
|
}
|
||||||
for(uint8_t j = 0; j < 4; j++) {
|
for(uint8_t j = 0; j < 4; j++) {
|
||||||
mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH);
|
mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH);
|
||||||
|
|
|
@ -71,7 +71,6 @@ class app {
|
||||||
void saveValues(void);
|
void saveValues(void);
|
||||||
void resetPayload(Inverter<>* iv);
|
void resetPayload(Inverter<>* iv);
|
||||||
String getStatistics(void);
|
String getStatistics(void);
|
||||||
String getLiveData(void);
|
|
||||||
String getJson(void);
|
String getJson(void);
|
||||||
bool getWifiApActive(void);
|
bool getWifiApActive(void);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ typedef enum {
|
||||||
} DevControlCmdType;
|
} DevControlCmdType;
|
||||||
|
|
||||||
typedef enum { // ToDo: to be verified by field tests
|
typedef enum { // ToDo: to be verified by field tests
|
||||||
|
NoPowerLimit = 0xffff, // ahoy internal value, no hoymiles value!
|
||||||
AbsolutNonPersistent = 0UL, // 0x0000
|
AbsolutNonPersistent = 0UL, // 0x0000
|
||||||
RelativNonPersistent = 1UL, // 0x0001
|
RelativNonPersistent = 1UL, // 0x0001
|
||||||
AbsolutPersistent = 256UL, // 0x0100
|
AbsolutPersistent = 256UL, // 0x0100
|
||||||
|
|
|
@ -121,10 +121,10 @@ class Inverter {
|
||||||
Inverter() {
|
Inverter() {
|
||||||
ts = 0;
|
ts = 0;
|
||||||
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
||||||
powerLimit[1] = 0x0000; //
|
powerLimit[1] = NoPowerLimit; //
|
||||||
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
||||||
devControlRequest = false;
|
devControlRequest = false;
|
||||||
devControlCmd = 0xff;
|
devControlCmd = InitDataState;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
fwVersion = 0;
|
fwVersion = 0;
|
||||||
lastAlarmMsg = "nothing";
|
lastAlarmMsg = "nothing";
|
||||||
|
@ -155,7 +155,7 @@ class Inverter {
|
||||||
// Fill with default commands
|
// Fill with default commands
|
||||||
enqueCommand<InfoCommand>(RealTimeRunData_Debug);
|
enqueCommand<InfoCommand>(RealTimeRunData_Debug);
|
||||||
if (fwVersion == 0)
|
if (fwVersion == 0)
|
||||||
{ // info needed maybe after "one nigth" (=> DC>0 to DC=0 and to DC>0) or reboot
|
{ // info needed maybe after "one night" (=> DC>0 to DC=0 and to DC>0) or reboot
|
||||||
enqueCommand<InfoCommand>(InverterDevInform_All);
|
enqueCommand<InfoCommand>(InverterDevInform_All);
|
||||||
}
|
}
|
||||||
if (actPowerLimit == 0xffff)
|
if (actPowerLimit == 0xffff)
|
||||||
|
@ -325,9 +325,7 @@ class Inverter {
|
||||||
assign = NULL;
|
assign = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cmd = getQueuedCmd();
|
switch (getQueuedCmd()) {
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case RealTimeRunData_Debug:
|
case RealTimeRunData_Debug:
|
||||||
// Do nothing will use default
|
// Do nothing will use default
|
||||||
break;
|
break;
|
||||||
|
@ -345,6 +343,7 @@ class Inverter {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTLN(DBG_INFO, "Parser not implemented");
|
DPRINTLN(DBG_INFO, "Parser not implemented");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String getAlarmStr(u_int16_t alarmCode)
|
String getAlarmStr(u_int16_t alarmCode)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -128,7 +128,7 @@
|
||||||
<p class="des">Serial Console</p>
|
<p class="des">Serial Console</p>
|
||||||
<label for="serEn">print inverter data</label>
|
<label for="serEn">print inverter data</label>
|
||||||
<input type="checkbox" class="cb" name="serEn" {SER_VAL_CB}/><br/>
|
<input type="checkbox" class="cb" name="serEn" {SER_VAL_CB}/><br/>
|
||||||
<label for="serDbg">print RF24 debug</label>
|
<label for="serDbg">Serial Debug</label>
|
||||||
<input type="checkbox" class="cb" name="serDbg" {SER_DBG_CB}/><br/>
|
<input type="checkbox" class="cb" name="serDbg" {SER_DBG_CB}/><br/>
|
||||||
<label for="serIntvl">Interval [s]</label>
|
<label for="serIntvl">Interval [s]</label>
|
||||||
<input type="text" class="text" name="serIntvl" value="{SER_INTVL}"/>
|
<input type="text" class="text" name="serIntvl" value="{SER_INTVL}"/>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
|
|
||||||
const uint16_t pwrLimitOptionValues[] {
|
const uint16_t pwrLimitOptionValues[] {
|
||||||
|
NoPowerLimit,
|
||||||
AbsolutNonPersistent,
|
AbsolutNonPersistent,
|
||||||
AbsolutPersistent,
|
AbsolutPersistent,
|
||||||
RelativNonPersistent,
|
RelativNonPersistent,
|
||||||
|
@ -25,6 +26,7 @@ const uint16_t pwrLimitOptionValues[] {
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* const pwrLimitOptions[] {
|
const char* const pwrLimitOptions[] {
|
||||||
|
"no power limit",
|
||||||
"absolute in Watt non persistent",
|
"absolute in Watt non persistent",
|
||||||
"absolute in Watt persistent",
|
"absolute in Watt persistent",
|
||||||
"relativ in percent non persistent",
|
"relativ in percent non persistent",
|
||||||
|
@ -216,7 +218,7 @@ void web::showSetup(void) {
|
||||||
|
|
||||||
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimitConType\">Active Power Limit Control Type</label>");
|
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimitConType\">Active Power Limit Control Type</label>");
|
||||||
inv += F("<select name=\"inv") + String(i) + F("PowerLimitControl\">");
|
inv += F("<select name=\"inv") + String(i) + F("PowerLimitControl\">");
|
||||||
for(uint8_t j = 0; j < 4; j++) {
|
for(uint8_t j = 0; j < 5; j++) {
|
||||||
inv += F("<option value=\"") + String(pwrLimitOptionValues[j]) + F("\"");
|
inv += F("<option value=\"") + String(pwrLimitOptionValues[j]) + F("\"");
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
if(iv->powerLimit[1] == pwrLimitOptionValues[j])
|
if(iv->powerLimit[1] == pwrLimitOptionValues[j])
|
||||||
|
@ -330,13 +332,14 @@ void web::showSave(void) {
|
||||||
iv->powerLimit[1] = actPwrLimitControl;
|
iv->powerLimit[1] = actPwrLimitControl;
|
||||||
iv->devControlCmd = ActivePowerContr;
|
iv->devControlCmd = ActivePowerContr;
|
||||||
iv->devControlRequest = true;
|
iv->devControlRequest = true;
|
||||||
if (iv->powerLimit[1] & 0x0001)
|
if ((iv->powerLimit[1] & 0x0001) == 0x0001)
|
||||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("%") );
|
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("%") );
|
||||||
else
|
else {
|
||||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W") );
|
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W") );
|
||||||
DPRINTLN(DBG_INFO, F("Power Limit Control Setting ") + String(iv->powerLimit[1]));
|
DPRINTLN(DBG_INFO, F("Power Limit Control Setting ") + String(iv->powerLimit[1]));
|
||||||
}
|
}
|
||||||
if (actPwrLimit == 0xffff){ // set to 100%
|
}
|
||||||
|
if (actPwrLimit == 0xffff) { // set to 100%
|
||||||
iv->powerLimit[0] = 100;
|
iv->powerLimit[0] = 100;
|
||||||
iv->powerLimit[1] = RelativPersistent;
|
iv->powerLimit[1] = RelativPersistent;
|
||||||
iv->devControlCmd = ActivePowerContr;
|
iv->devControlCmd = ActivePowerContr;
|
||||||
|
@ -431,7 +434,84 @@ void web::showVisualization(void) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void web::showLiveData(void) {
|
void web::showLiveData(void) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("web::showLiveData"));
|
DPRINTLN(DBG_VERBOSE, F("web::showLiveData"));
|
||||||
mWeb->send(200, F("text/html"), mMain->getLiveData());
|
|
||||||
|
String modHtml;
|
||||||
|
for (uint8_t id = 0; id < mMain->mSys->getNumInverters(); id++) {
|
||||||
|
Inverter<> *iv = mMain->mSys->getInverterByPos(id);
|
||||||
|
if (NULL != iv) {
|
||||||
|
#ifdef LIVEDATA_VISUALIZED
|
||||||
|
uint8_t modNum, pos;
|
||||||
|
switch (iv->type) {
|
||||||
|
default:
|
||||||
|
case INV_TYPE_1CH: modNum = 1; break;
|
||||||
|
case INV_TYPE_2CH: modNum = 2; break;
|
||||||
|
case INV_TYPE_4CH: modNum = 4; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
modHtml += F("<div class=\"iv\">"
|
||||||
|
"<div class=\"ch-iv\"><span class=\"head\">")
|
||||||
|
+ String(iv->name) + F(" Limit ")
|
||||||
|
+ String(iv->actPowerLimit) + F("%");
|
||||||
|
if(NoPowerLimit == iv->powerLimit[1])
|
||||||
|
modHtml += F(" (not controlled)");
|
||||||
|
modHtml += F(" | last Alarm: ") + iv->lastAlarmMsg + F("</span>");
|
||||||
|
|
||||||
|
uint8_t list[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PCT, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_PRA, FLD_ALARM_MES_ID};
|
||||||
|
|
||||||
|
for (uint8_t fld = 0; fld < 11; fld++) {
|
||||||
|
pos = (iv->getPosByChFld(CH0, list[fld]));
|
||||||
|
if (0xff != pos) {
|
||||||
|
modHtml += F("<div class=\"subgrp\">");
|
||||||
|
modHtml += F("<span class=\"value\">") + String(iv->getValue(pos));
|
||||||
|
modHtml += F("<span class=\"unit\">") + String(iv->getUnit(pos)) + F("</span></span>");
|
||||||
|
modHtml += F("<span class=\"info\">") + String(iv->getFieldName(pos)) + F("</span>");
|
||||||
|
modHtml += F("</div>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modHtml += "</div>";
|
||||||
|
|
||||||
|
for (uint8_t ch = 1; ch <= modNum; ch++) {
|
||||||
|
modHtml += F("<div class=\"ch\"><span class=\"head\">");
|
||||||
|
if (iv->chName[ch - 1][0] == 0)
|
||||||
|
modHtml += F("CHANNEL ") + String(ch);
|
||||||
|
else
|
||||||
|
modHtml += String(iv->chName[ch - 1]);
|
||||||
|
modHtml += F("</span>");
|
||||||
|
for (uint8_t j = 0; j < 6; j++) {
|
||||||
|
switch (j) {
|
||||||
|
default: pos = (iv->getPosByChFld(ch, FLD_UDC)); break;
|
||||||
|
case 1: pos = (iv->getPosByChFld(ch, FLD_IDC)); break;
|
||||||
|
case 2: pos = (iv->getPosByChFld(ch, FLD_PDC)); break;
|
||||||
|
case 3: pos = (iv->getPosByChFld(ch, FLD_YD)); break;
|
||||||
|
case 4: pos = (iv->getPosByChFld(ch, FLD_YT)); break;
|
||||||
|
case 5: pos = (iv->getPosByChFld(ch, FLD_IRR)); break;
|
||||||
|
}
|
||||||
|
if (0xff != pos) {
|
||||||
|
modHtml += F("<span class=\"value\">") + String(iv->getValue(pos));
|
||||||
|
modHtml += F("<span class=\"unit\">") + String(iv->getUnit(pos)) + F("</span></span>");
|
||||||
|
modHtml += F("<span class=\"info\">") + String(iv->getFieldName(pos)) + F("</span>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modHtml += "</div>";
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
modHtml += F("<div class=\"ts\">Last received data requested at: ") + mMain->getDateTimeStr(iv->ts) + F("</div>");
|
||||||
|
modHtml += F("</div>");
|
||||||
|
#else
|
||||||
|
// dump all data to web frontend
|
||||||
|
modHtml = F("<pre>");
|
||||||
|
char topic[30], val[10];
|
||||||
|
for (uint8_t i = 0; i < iv->listLen; i++) {
|
||||||
|
snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, iv->getFieldName(i));
|
||||||
|
snprintf(val, 10, "%.3f %s", iv->getValue(i), iv->getUnit(i));
|
||||||
|
modHtml += String(topic) + ": " + String(val) + "\n";
|
||||||
|
}
|
||||||
|
modHtml += F("</pre>");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mWeb->send(200, F("text/html"), modHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue