mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-29 18:26:21 +02:00
Patch no_eeprom_pl
This commit is contained in:
parent
f53933b473
commit
7c7a7d25b8
8 changed files with 25 additions and 92 deletions
|
@ -121,31 +121,13 @@ void app::loop(void) {
|
|||
mPayload[iv->id].txId = p->packet[0];
|
||||
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
|
||||
iv->devControlRequest = false;
|
||||
switch (p->packet[12]) {
|
||||
case ActivePowerContr:
|
||||
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
|
||||
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]);
|
||||
updateCrc();
|
||||
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"));
|
||||
} 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]));
|
||||
iv->devControlCmd = Init;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (iv->devControlCmd == ActivePowerContr) {
|
||||
//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_CON + iv->id * 2, (uint16_t *)&(iv->powerLimit[1]));
|
||||
DPRINTLN(DBG_INFO, F("Inverter has not accepted power limit set point"));
|
||||
}
|
||||
iv->devControlCmd = Init;
|
||||
break;
|
||||
if (p->packet[12] == ActivePowerContr && p->packet[13] == 0x00) {
|
||||
if (p->packet[10] == 0x00 && p->packet[11] == 0x00)
|
||||
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]));
|
||||
else
|
||||
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has NOT accepted power limit set point") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
|
||||
}
|
||||
iv->devControlCmd = Init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +236,7 @@ void app::loop(void) {
|
|||
DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()));
|
||||
DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX));
|
||||
}
|
||||
if(iv->devControlRequest && ((iv->devControlCmd != ActivePowerContr) || ((iv->devControlCmd == ActivePowerContr) && (iv->powerLimit[0] > 0) && (iv->powerLimit[1] != NoPowerLimit)))) { // prevent to "switch off"
|
||||
if(iv->devControlRequest) {
|
||||
if(mConfig.serialDebug)
|
||||
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);
|
||||
|
@ -782,23 +764,6 @@ void app::loadEEpconfig(void) {
|
|||
if(0ULL != invSerial) {
|
||||
iv = mSys->addInverter(name, invSerial, modPwr);
|
||||
if(NULL != iv) { // will run once on every dtu boot
|
||||
mEep->read(ADDR_INV_PWR_LIM + (i * 2),(uint16_t *)&(iv->powerLimit[0]));
|
||||
mEep->read(ADDR_INV_PWR_LIM_CON + (i * 2),(uint16_t *)&(iv->powerLimit[1]));
|
||||
// only set it, if it is changed by user. Default value in the html setup page is -1 = 0xffff
|
||||
// it is "doppelt-gemoppelt" because the inverter shall remember the setting if the dtu makes a power cycle / reboot
|
||||
if (iv->powerLimit[0] != 0xffff) {
|
||||
iv->devControlCmd = ActivePowerContr; // set active power limit
|
||||
DPRINT(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX));
|
||||
if(iv->powerLimit[1] != NoPowerLimit) {
|
||||
DBGPRINT(F(", Power Limit: ") + String(iv->powerLimit[0]));
|
||||
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++) {
|
||||
mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH);
|
||||
}
|
||||
|
@ -828,8 +793,6 @@ void app::saveValues(void) {
|
|||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
iv = mSys->getInverterByPos(i, false);
|
||||
mEep->write(ADDR_INV_ADDR + (i * 8), iv->serial.u64);
|
||||
mEep->write(ADDR_INV_PWR_LIM + i * 2, iv->powerLimit[0]);
|
||||
mEep->write(ADDR_INV_PWR_LIM_CON + i * 2, iv->powerLimit[1]);
|
||||
mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), iv->name, MAX_NAME_LENGTH);
|
||||
// max channel power / name
|
||||
for(uint8_t j = 0; j < 4; j++) {
|
||||
|
|
|
@ -58,7 +58,6 @@ typedef enum {
|
|||
} DevControlCmdType;
|
||||
|
||||
typedef enum {
|
||||
NoPowerLimit = 0xffff, // ahoy internal value, no hoymiles value!
|
||||
AbsolutNonPersistent = 0UL, // 0x0000
|
||||
RelativNonPersistent = 1UL, // 0x0001
|
||||
AbsolutPersistent = 256UL, // 0x0100
|
||||
|
@ -166,10 +165,8 @@ typedef struct {
|
|||
#define ADDR_INV_CH_NAME ADDR_INV_CH_PWR + INV_CH_CH_PWR_LEN
|
||||
#define ADDR_INV_INTERVAL ADDR_INV_CH_NAME + INV_CH_CH_NAME_LEN
|
||||
#define ADDR_INV_MAX_RTRY ADDR_INV_INTERVAL + INV_INTERVAL_LEN
|
||||
#define ADDR_INV_PWR_LIM ADDR_INV_MAX_RTRY + INV_MAX_RTRY_LEN
|
||||
#define ADDR_INV_PWR_LIM_CON ADDR_INV_PWR_LIM + INV_PWR_LIM_LEN
|
||||
|
||||
#define ADDR_NEXT ADDR_INV_PWR_LIM_CON + INV_PWR_LIM_LEN
|
||||
#define ADDR_NEXT ADDR_INV_MAX_RTRY + INV_INTERVAL_LEN
|
||||
|
||||
|
||||
#define ADDR_SETTINGS_CRC ADDR_NEXT + 2
|
||||
|
|
|
@ -126,7 +126,7 @@ class Inverter {
|
|||
|
||||
Inverter() {
|
||||
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
||||
powerLimit[1] = NoPowerLimit; // default power limit setting
|
||||
powerLimit[1] = AbsolutNonPersistent; // default power limit setting
|
||||
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
||||
devControlRequest = false;
|
||||
devControlCmd = InitDataState;
|
||||
|
|
|
@ -33,6 +33,18 @@
|
|||
<input type="button" value="Turn Off" class="btn" id="turnoff"/>
|
||||
<input type="button" value="Turn On" class="btn" id="turnon"/>
|
||||
<br/>
|
||||
<label>Send Power Limit:</label>
|
||||
<input type="text" class="text" name="pwrlimval" maxlength="4" size="20%"/>
|
||||
<label></label>
|
||||
<select name="pwrlimcntrl" id="pwrlimcntrl">
|
||||
<option value="65535">select the unit and persistence</option>
|
||||
<option value="0">absolute in Watt non persistent</option>
|
||||
<option value="1">relativ in percent non persistent</option>
|
||||
<option value="256">absolute in Watt persistent</option>
|
||||
<option value="257">relativ in percent persistent</option>
|
||||
</select>
|
||||
<input type="button" value="Send PL" class="btn" id="sendpwrlim"/>
|
||||
<br/>
|
||||
Ctrl result: <span id="result">n/a</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -161,7 +173,7 @@
|
|||
obj.inverter = get_selected_iv();
|
||||
obj.cmd = 11;
|
||||
obj.tx_request = 81;
|
||||
obj.payload = [2000, 1];
|
||||
obj.payload = [100, 1];
|
||||
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
|
||||
});
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
|
||||
document.getElementsByName("btnAdd")[0].addEventListener("click", function() {
|
||||
if(highestId < (maxInv-1))
|
||||
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""],"power_limit":1500,"power_limit_option":65535}'), highestId + 1);
|
||||
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
|
||||
});
|
||||
|
||||
function ivHtml(obj, id) {
|
||||
|
@ -163,20 +163,11 @@
|
|||
}
|
||||
});
|
||||
|
||||
for(var i of [["Name", "name", "Name*", 32], ["ActivePowerLimit", "power_limit", "Active Power Limit", 5]]) {
|
||||
for(var i of [["Name", "name", "Name*", 32]]) { // so richtig?
|
||||
iv.appendChild(lbl(id + i[0], i[2]));
|
||||
iv.appendChild(inp(id + i[0], obj[i[1]], i[3]));
|
||||
}
|
||||
|
||||
iv.appendChild(lbl(id + "PowerLimitControl", "Active Power Limit Control Type"));
|
||||
iv.appendChild(sel(id + "PowerLimitControl", [
|
||||
[65535, "no power limit"],
|
||||
[0, "absolute in Watt non persistent"],
|
||||
[1, "absolute in Watt persistent"],
|
||||
[256, "relativ in percent non persistent"],
|
||||
[257, "relativ in percent persistent"]
|
||||
], obj.power_limit_option));
|
||||
|
||||
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4], ["ModName", "ch_name", "Module Name", 16]]) {
|
||||
var cl = (re.test(obj["serial"])) ? null : ["hide"];
|
||||
iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0]));
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
var limit = iv["power_limit_read"] + "%";
|
||||
if(limit == "65535%")
|
||||
limit = "n/a";
|
||||
var ctrl = (iv["power_limit_active"]) ? "" : " (not controlled)";
|
||||
ch0.appendChild(span(iv["name"] + " Limit " + limit + ctrl + " | last Alarm: " + iv["last_alarm"], ["head"]));
|
||||
ch0.appendChild(span(iv["name"] + " Limit " + limit + " | last Alarm: " + iv["last_alarm"], ["head"]));
|
||||
|
||||
for(var j = 0; j < root.ch0_fld_names.length; j++) {
|
||||
var val = Math.round(iv["ch"][0][j] * 100) / 100;
|
||||
|
|
|
@ -237,31 +237,6 @@ void web::showSave(AsyncWebServerRequest *request) {
|
|||
memset(buf, 0, 20);
|
||||
iv->serial.u64 = mMain->Serial2u64(buf);
|
||||
|
||||
// active power limit
|
||||
uint16_t actPwrLimit = request->arg("inv" + String(i) + "ActivePowerLimit").toInt();
|
||||
uint16_t actPwrLimitControl = request->arg("inv" + String(i) + "PowerLimitControl").toInt();
|
||||
if(NoPowerLimit != actPwrLimitControl) {
|
||||
if (actPwrLimit != 0xffff && actPwrLimit > 0){
|
||||
iv->powerLimit[0] = actPwrLimit;
|
||||
iv->powerLimit[1] = actPwrLimitControl;
|
||||
iv->devControlCmd = ActivePowerContr;
|
||||
iv->devControlRequest = true;
|
||||
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("%") );
|
||||
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 Control Setting ") + String(iv->powerLimit[1]));
|
||||
}
|
||||
}
|
||||
if (actPwrLimit == 0xffff) { // set to 100%
|
||||
iv->powerLimit[0] = 100;
|
||||
iv->powerLimit[1] = RelativPersistent;
|
||||
iv->devControlCmd = ActivePowerContr;
|
||||
iv->devControlRequest = true;
|
||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to unlimted"));
|
||||
}
|
||||
}
|
||||
|
||||
// name
|
||||
request->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH);
|
||||
|
||||
|
|
|
@ -156,9 +156,6 @@ void webApi::getInverterList(JsonObject obj) {
|
|||
obj2[F("ch_max_power")][j] = iv->chMaxPwr[j];
|
||||
obj2[F("ch_name")][j] = iv->chName[j];
|
||||
}
|
||||
|
||||
obj2[F("power_limit")] = iv->powerLimit[0];
|
||||
obj2[F("power_limit_option")] = iv->powerLimit[1];
|
||||
}
|
||||
}
|
||||
obj[F("interval")] = String(mConfig->sendInterval);
|
||||
|
@ -274,7 +271,6 @@ void webApi::getLive(JsonObject obj) {
|
|||
obj2[F("name")] = String(iv->name);
|
||||
obj2[F("channels")] = iv->channels;
|
||||
obj2[F("power_limit_read")] = round3(iv->actPowerLimit);
|
||||
obj2[F("power_limit_active")] = NoPowerLimit != iv->powerLimit[1];
|
||||
obj2[F("last_alarm")] = String(iv->lastAlarmMsg);
|
||||
obj2[F("ts_last_success")] = rec->ts;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue