Skip to content

Commit

Permalink
0.8.4
Browse files Browse the repository at this point in the history
* introduced tabs in WebGUI (inverter settings)
* added inverter-wise power level and frequency
  • Loading branch information
lumapu committed Nov 11, 2023
1 parent c98d35d commit efdac96
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 79 deletions.
2 changes: 2 additions & 0 deletions src/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## 0.8.4 - 2023-11-10
* changed MqTT alarm topic, removed retained flag #1212
* reduce last_success MQTT messages (#1124)
* introduced tabs in WebGUI (inverter settings)
* added inverter-wise power level and frequency

## 0.8.3 - 2023-11-09
* fix yield day reset during day #848
Expand Down
2 changes: 1 addition & 1 deletion src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void app::setup() {
DBGPRINTLN(F("false"));

if(mConfig->nrf.enabled) {
mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso);
mNrfRadio.setup(mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso);
mNrfRadio.enableDebug();
}
#if defined(ESP32)
Expand Down
3 changes: 0 additions & 3 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,6 @@
#define LED_HIGH_ACTIVE false
#endif

// default NRF24 power, possible values (0 - 3)
#define DEF_AMPLIFIERPOWER 1

// number of packets hold in buffer
#define PACKET_BUFFER_SIZE 30

Expand Down
43 changes: 36 additions & 7 deletions src/config/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout
* */

#define CONFIG_VERSION 1


#define PROT_MASK_INDEX 0x0001
#define PROT_MASK_LIVE 0x0002
Expand Down Expand Up @@ -88,7 +90,6 @@ typedef struct {
uint8_t pinMiso;
uint8_t pinMosi;
uint8_t pinSclk;
uint8_t amplifierPower;
} cfgNrf24_t;

typedef struct {
Expand Down Expand Up @@ -142,6 +143,8 @@ typedef struct {
uint16_t chMaxPwr[6];
double yieldCor[6]; // YieldTotal correction value
char chName[6][MAX_NAME_LENGTH];
uint8_t frequency;
uint8_t powerLevel;
} cfgIv_t;

typedef struct {
Expand Down Expand Up @@ -188,6 +191,7 @@ typedef struct {
cfgInst_t inst;
plugins_t plugin;
bool valid;
uint16_t configVersion;
} settings_t;

class settings {
Expand Down Expand Up @@ -284,6 +288,7 @@ class settings {
if(root.containsKey(F("led"))) jsonLed(root[F("led")]);
if(root.containsKey(F("plugin"))) jsonPlugin(root[F("plugin")]);
if(root.containsKey(F("inst"))) jsonInst(root[F("inst")]);
getConfigVersion(root.as<JsonObject>());
}
else {
Serial.println(F("failed to parse json, using default config"));
Expand All @@ -299,6 +304,7 @@ class settings {

DynamicJsonDocument json(MAX_ALLOWED_BUF_SIZE);
JsonObject root = json.to<JsonObject>();
json[F("version")] = CONFIG_VERSION;
jsonNetwork(root.createNestedObject(F("wifi")), true);
jsonNrf(root.createNestedObject(F("nrf")), true);
#if defined(ESP32)
Expand Down Expand Up @@ -391,7 +397,6 @@ class settings {
mCfg.nrf.pinMosi = DEF_NRF_MOSI_PIN;
mCfg.nrf.pinSclk = DEF_NRF_SCLK_PIN;

mCfg.nrf.amplifierPower = DEF_AMPLIFIERPOWER & 0x03;
mCfg.nrf.enabled = true;

#if defined(ESP32)
Expand Down Expand Up @@ -436,6 +441,11 @@ class settings {
mCfg.inst.rstMaxValsMidNight = false;
mCfg.inst.yieldEffiency = 0.955f;

for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
mCfg.inst.iv[i].powerLevel = 0xff; // impossible high value
mCfg.inst.iv[i].frequency = 0x12; // 863MHz (minimum allowed frequency)
}

mCfg.led.led0 = DEF_LED0;
mCfg.led.led1 = DEF_LED1;
mCfg.led.led_high_active = LED_HIGH_ACTIVE;
Expand All @@ -446,13 +456,30 @@ class settings {
mCfg.plugin.display.contrast = 60;
mCfg.plugin.display.pxShift = true;
mCfg.plugin.display.rot = 0;
mCfg.plugin.display.disp_data = DEF_PIN_OFF; // SDA
mCfg.plugin.display.disp_clk = DEF_PIN_OFF; // SCL
mCfg.plugin.display.disp_data = DEF_PIN_OFF; // SDA
mCfg.plugin.display.disp_clk = DEF_PIN_OFF; // SCL
mCfg.plugin.display.disp_cs = DEF_PIN_OFF;
mCfg.plugin.display.disp_reset = DEF_PIN_OFF;
mCfg.plugin.display.disp_busy = DEF_PIN_OFF;
mCfg.plugin.display.disp_dc = DEF_PIN_OFF;
}
}

void loadAddedDefaults() {
if(0 == mCfg.configVersion) {
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
mCfg.inst.iv[i].powerLevel = 0xff; // impossible high value
mCfg.inst.iv[i].frequency = 0x12; // 863MHz (minimum allowed frequency)
}
}
}

void getConfigVersion(JsonObject obj) {
getVal<uint16_t>(obj, F("version"), &mCfg.configVersion);
DPRINT(DBG_INFO, F("Config Version: "));
DBGPRINTLN(String(mCfg.configVersion));
if(CONFIG_VERSION != mCfg.configVersion)
loadAddedDefaults();
}

void jsonNetwork(JsonObject obj, bool set = false) {
if(set) {
Expand Down Expand Up @@ -506,7 +533,6 @@ class settings {
obj[F("sclk")] = mCfg.nrf.pinSclk;
obj[F("mosi")] = mCfg.nrf.pinMosi;
obj[F("miso")] = mCfg.nrf.pinMiso;
obj[F("pwr")] = mCfg.nrf.amplifierPower;
obj[F("en")] = (bool) mCfg.nrf.enabled;
} else {
getVal<uint16_t>(obj, F("intvl"), &mCfg.nrf.sendInterval);
Expand All @@ -516,7 +542,6 @@ class settings {
getVal<uint8_t>(obj, F("sclk"), &mCfg.nrf.pinSclk);
getVal<uint8_t>(obj, F("mosi"), &mCfg.nrf.pinMosi);
getVal<uint8_t>(obj, F("miso"), &mCfg.nrf.pinMiso);
getVal<uint8_t>(obj, F("pwr"), &mCfg.nrf.amplifierPower);
#if !defined(ESP32)
mCfg.nrf.enabled = true; // ESP8266, read always as enabled
#else
Expand Down Expand Up @@ -707,6 +732,8 @@ class settings {
obj[F("en")] = (bool)cfg->enabled;
obj[F("name")] = cfg->name;
obj[F("sn")] = cfg->serial.u64;
obj[F("freq")] = cfg->frequency;
obj[F("pa")] = cfg->powerLevel;
for(uint8_t i = 0; i < 6; i++) {
obj[F("yield")][i] = cfg->yieldCor[i];
obj[F("pwr")][i] = cfg->chMaxPwr[i];
Expand All @@ -716,6 +743,8 @@ class settings {
getVal<bool>(obj, F("en"), &cfg->enabled);
getChar(obj, F("name"), cfg->name, MAX_NAME_LENGTH);
getVal<uint64_t>(obj, F("sn"), &cfg->serial.u64);
getVal<uint8_t>(obj, F("freq"), &cfg->frequency);
getVal<uint8_t>(obj, F("pa"), &cfg->powerLevel);
uint8_t size = 4;
if(obj.containsKey(F("pwr")))
size = obj[F("pwr")].size();
Expand Down
2 changes: 1 addition & 1 deletion src/hm/Communication.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class Communication : public CommQueue<> {
q->iv->radioStatistics.rxFailNoAnser++; // got nothing
mHeu.setGotNothing(q->iv);
if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ);
q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ));
mWaitTimeout = millis() + 1000;
}
} else
Expand Down
2 changes: 2 additions & 0 deletions src/hm/hmInverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class Inverter {
statistics_t radioStatistics; // information about transmitted, failed, ... packets
int8_t txRfQuality[5]; // heuristics tx quality (check 'Heuristics.h')
uint8_t txRfChId; // RF TX channel id
uint8_t curCmtFreq; // current used CMT frequency, used to check if freq. was changed during runtime

static uint32_t *timestamp; // system timestamp
static cfgInst_t *generalConfig; // general inverter configuration from setup
Expand Down Expand Up @@ -194,6 +195,7 @@ class Inverter {
initAssignment(&recordConfig, SystemConfigPara);
initAssignment(&recordAlarm, AlarmData);
toRadioId();
curCmtFreq = this->config->frequency; // update to frequency read from settings
}

uint8_t getPosByChFld(uint8_t channel, uint8_t fieldId, record_t<> *rec) {
Expand Down
7 changes: 3 additions & 4 deletions src/hm/hmRadio.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class HmRadio : public Radio {
}
~HmRadio() {}

void setup(uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) {
void setup(uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) {
DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup"));
pinMode(irq, INPUT_PULLUP);

Expand Down Expand Up @@ -81,9 +81,7 @@ class HmRadio : public Radio {
// enable all receiving interrupts
mNrf24.maskIRQ(false, false, false);

DPRINT(DBG_INFO, F("RF24 Amp Pwr: RF24_PA_"));
DPRINTLN(DBG_INFO, String(rf24AmpPowerNames[ampPwr]));
mNrf24.setPALevel(ampPwr & 0x03);
mNrf24.setPALevel(1); // low is default

if(mNrf24.isChipConnected()) {
DPRINTLN(DBG_INFO, F("Radio Config:"));
Expand Down Expand Up @@ -269,6 +267,7 @@ class HmRadio : public Radio {
}

void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) {
mNrf24.setPALevel(iv->config->powerLevel & 0x03);
updateCrcs(&len, appendCrc16);

// set TX and RX channels
Expand Down
4 changes: 4 additions & 0 deletions src/hms/cmt2300a.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ class Cmt2300a {
return HOY_BASE_FREQ_KHZ + (mCurCh * FREQ_STEP_KHZ);
}

uint8_t getCurrentChannel(void) {
return mCurCh;
}

void setPaLevel(int8_t level) {
if(level < -10)
level = -10;
Expand Down
16 changes: 15 additions & 1 deletion src/hms/hmsRadio.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ class CmtRadio : public Radio {
uint8_t fromCh = mCmt.freq2Chan(fromkHz);
uint8_t toCh = mCmt.freq2Chan(tokHz);

return switchFrequencyCh(iv, fromCh, toCh);
}

private:
bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) {
if((0xff == fromCh) || (0xff == toCh))
return false;

Expand All @@ -75,8 +80,17 @@ class CmtRadio : public Radio {
return true;
}

private:
void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) {
// frequency was changed during runtime
if(iv->curCmtFreq != iv->config->frequency) {
if(switchFrequencyCh(iv, iv->curCmtFreq, iv->config->frequency))
iv->curCmtFreq = iv->config->frequency;
} else {
// inverters have maybe different settings regarding frequency
if(mCmt.getCurrentChannel() != iv->config->frequency)
mCmt.switchChannel(iv->config->frequency);
}

updateCrcs(&len, appendCrc16);

if(mSerialDebug) {
Expand Down
12 changes: 10 additions & 2 deletions src/web/RestApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,14 @@ class RestApi {
obj2[F("name")] = String(iv->config->name);
obj2[F("serial")] = String(iv->config->serial.u64, HEX);
obj2[F("channels")] = iv->channels;
obj2[F("version")] = String(iv->getFwVersion());
obj2[F("freq")] = iv->config->frequency;
if(0xff == iv->config->powerLevel) {
if((IV_HMT == iv->ivGen) || (IV_HMS == iv->ivGen))
obj2[F("pa")] = 30; // 20dBm
else
obj2[F("pa")] = 1; // low
} else
obj2[F("pa")] = iv->config->powerLevel;

for(uint8_t j = 0; j < iv->channels; j ++) {
obj2[F("ch_yield_cor")][j] = (double)iv->config->yieldCor[j];
Expand Down Expand Up @@ -529,7 +536,6 @@ class RestApi {
void getRadioNrf(JsonObject obj) {
obj[F("en")] = (bool) mConfig->nrf.enabled;
obj[F("isconnected")] = mRadioNrf->isChipConnected();
obj[F("power_level")] = mConfig->nrf.amplifierPower;
obj[F("dataRate")] = mRadioNrf->getDataRate();
//obj[F("isPVariant")] = mRadioNrf->isPVariant();
}
Expand Down Expand Up @@ -736,6 +742,8 @@ class RestApi {
case 0x61: iv->type = INV_TYPE_4CH; iv->channels = 4; break;
default: break;
}
iv->config->frequency = jsonIn[F("freq")];
iv->config->powerLevel = jsonIn[F("pa")];
mApp->saveSettings(false); // without reboot
} else {
jsonOut[F("error")] = F("unknown cmd");
Expand Down
42 changes: 33 additions & 9 deletions src/web/html/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,34 @@ function badge(success, text, second="error") {
return ml("span", {class: "badge badge-" + ((success) ? "success" : second)}, text);
}

function tabChange(id) {
var els = document.getElementsByClassName("nav-link");
[].forEach.call(els, function(e) {
if(e.id != id)
e.classList.remove('active');
else
e.classList.add('active');
});

els = document.getElementsByClassName("tab-content");
[].forEach.call(els, function(e) {
if(e.id == ("div"+id.substring(3)))
e.classList.remove('hide');
else
e.classList.add('hide');
});
}

function tabs(items) {
var li = [];
var cl = " active";
for(it of items) {
li.push(ml("li", {class: "nav-item"},ml("a", {id: "tab"+it, class: "nav-link" + cl, href: "#", onclick: function(){tabChange(this.id)}}, it)))
cl = "";
}
return ml("ul", {class: "nav nav-tabs mb-4"}, li);
}

function des(val) {
e = document.createElement('p');
e.classList.add("subdes");
Expand Down Expand Up @@ -223,13 +251,11 @@ function inp(name, val, max=32, cl=["text"], id=null, type=null, pattern=null, t
}

function sel(name, options, selId) {
e = document.createElement('select');
e.name = name;
var o = [];
for(it of options) {
o = opt(it[0], it[1], (it[0] == selId));
e.appendChild(o);
o.push(opt(it[0], it[1], (it[0] == selId)));
}
return e;
return ml("select", {name: name}, o);
}

function selDelAllOpt(sel) {
Expand All @@ -240,9 +266,7 @@ function selDelAllOpt(sel) {
}

function opt(val, html, sel=false) {
o = document.createElement('option');
o.value = val;
o.innerHTML = html;
var o = ml("option", {value: val}, html);
if(sel)
o.selected = true;
return o;
Expand Down Expand Up @@ -301,7 +325,7 @@ function svg(data=null, w=24, h=24, cl=null, tooltip=null) {
function modal(title, body) {
if(null == document.getElementById("modal")) {
document.getElementById("wrapper").append(
ml("div", {id: "modal-wrapper", class: "modal", onclick: modalClose}),
ml("div", {id: "modal-wrapper", onclick: modalClose}),
ml("div", {id: "modal", class: "modal"},
ml("div", {class: "modal-content"}, [
ml("div", {class: "modal-header"}, [
Expand Down
Loading

0 comments on commit efdac96

Please sign in to comment.