mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-29 08:46:11 +02:00
0.8.4
* introduced tabs in WebGUI (inverter settings) * added inverter-wise power level and frequency
This commit is contained in:
parent
c98d35d7c4
commit
efdac9634f
15 changed files with 241 additions and 80 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -88,7 +90,6 @@ typedef struct {
|
|||
uint8_t pinMiso;
|
||||
uint8_t pinMosi;
|
||||
uint8_t pinSclk;
|
||||
uint8_t amplifierPower;
|
||||
} cfgNrf24_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -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 {
|
||||
|
@ -188,6 +191,7 @@ typedef struct {
|
|||
cfgInst_t inst;
|
||||
plugins_t plugin;
|
||||
bool valid;
|
||||
uint16_t configVersion;
|
||||
} settings_t;
|
||||
|
||||
class settings {
|
||||
|
@ -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"));
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -454,6 +464,23 @@ class settings {
|
|||
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) {
|
||||
char buf[16];
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -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:"));
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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"}, [
|
||||
|
|
|
@ -438,6 +438,23 @@
|
|||
[47, "GPIO47"],
|
||||
[48, "GPIO48"],
|
||||
];
|
||||
var nrfPa = [
|
||||
[0, "MIN (recommended)"],
|
||||
[1, "LOW"],
|
||||
[2, "HIGH"],
|
||||
[3, "MAX (experimental)"]
|
||||
];
|
||||
var esp32cmtPa = [];
|
||||
var esp32cmtFreq = [];
|
||||
var freqFmt = new Intl.NumberFormat('en-US', {
|
||||
minimumIntegerDigits: 3,
|
||||
minimumFractionDigits: 2
|
||||
});
|
||||
for(var i = 0; i < 31; i++) {
|
||||
esp32cmtPa.push([i, String(i-10) + " dBm"]);
|
||||
if(i < 29)
|
||||
esp32cmtFreq.push([i, freqFmt.format(860 + i*0.25) + " MHz"]);
|
||||
}
|
||||
/*ENDIF_ESP32*/
|
||||
var led_high_active = [
|
||||
[0, "low active"],
|
||||
|
@ -647,6 +664,7 @@
|
|||
ml("th", {}, "Name (optional)"),
|
||||
ml("th", {}, "Yield Correction [kWh] (optional)")
|
||||
]));
|
||||
|
||||
for(let i = 0; i < 6; i++) {
|
||||
lines.push(ml("tr", {id: "ch"+i}, [
|
||||
ml("td", {}, String(i+1)),
|
||||
|
@ -655,29 +673,54 @@
|
|||
ml("td", {}, ml("input", {name: "yld_c"+i, class: "text", type: "number", max: 999999, value: obj.ch_yield_cor[i]}, null))
|
||||
]));
|
||||
}
|
||||
|
||||
var cbEn = ml("input", {name: "enable", type: "checkbox"}, null);
|
||||
if(obj.enabled)
|
||||
cbEn.checked = true;
|
||||
var ser = ml("input", {name: "ser", class: "text", type: "number", max: 138999999999, value: obj.serial}, null);
|
||||
var html = ml("div", {}, [
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4"}, "Serial"),
|
||||
ml("div", {class: "col-8"}, ser)
|
||||
]),
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4"}, "Name"),
|
||||
ml("div", {class: "col-8"}, ml("input", {name: "name", class: "text", type: "text", value: obj.name}, null))
|
||||
]),
|
||||
tabs(["General", "Inputs", "Radio"]),
|
||||
ml("div", {id: "divGeneral", class: "tab-content"}, [
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4"}, "Enable"),
|
||||
ml("div", {class: "col-8"}, cbEn)
|
||||
]),
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4 mt-2"}, "Serial"),
|
||||
ml("div", {class: "col-8"}, ser)
|
||||
]),
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4 mt-2"}, "Name"),
|
||||
ml("div", {class: "col-8"}, ml("input", {name: "name", class: "text", type: "text", value: obj.name}, null))
|
||||
])
|
||||
]),
|
||||
ml("div", {id: "divInputs", class: "tab-content hide"}, [
|
||||
ml("div", {class: "row mb-3"},
|
||||
ml("table", {class: "table"},
|
||||
ml("tbody", {}, lines)
|
||||
)
|
||||
),
|
||||
)
|
||||
]),
|
||||
ml("div", {id: "divRadio", class: "tab-content hide"}, [
|
||||
ml("input", {type: "hidden", name: "isnrf"}, null),
|
||||
ml("div", {id: "setcmt"}, [
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4 mt-2"}, "Frequency"),
|
||||
ml("div", {class: "col-8"}, sel("freq", esp32cmtFreq, obj.freq))
|
||||
]),
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4 mt-2"}, "Power Level"),
|
||||
ml("div", {class: "col-8"}, sel("cmtpa", esp32cmtPa, obj.pa))
|
||||
]),
|
||||
]),
|
||||
ml("div", {id: "setnrf"},
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-4 mt-2"}, "Power Level"),
|
||||
ml("div", {class: "col-8"}, sel("nrfpa", nrfPa, obj.pa))
|
||||
]),
|
||||
),
|
||||
]),
|
||||
ml("div", {class: "row mt-5"}, [
|
||||
ml("div", {class: "col-8", id: "res"}, ""),
|
||||
ml("div", {class: "col-4 a-r"}, ml("input", {type: "button", value: "save", class: "btn", onclick: function() { ivSave(); }}, null))
|
||||
])
|
||||
|
@ -685,28 +728,34 @@
|
|||
|
||||
['keyup', 'change'].forEach(function(evt) {
|
||||
ser.addEventListener(evt, (e) => {
|
||||
var serial = ser.value.substring(0,4);
|
||||
var sn = parseInt(ser.value, 16);
|
||||
sn = Math.floor(sn / Math.pow(2, 32));
|
||||
|
||||
var max = 1;
|
||||
switch(sn & 0x00f0) {
|
||||
case 0x0010: max = 1; break;
|
||||
case 0x0040: max = 2; break;
|
||||
case 0x0060: max = 4; break;
|
||||
case 0x0080: max = 6; break;
|
||||
}
|
||||
for(var i = 0; i < 6; i++) {
|
||||
setHide("ch"+i, true);
|
||||
setHide("ch"+i, (i >= max));
|
||||
}
|
||||
|
||||
if(serial.charAt(0) == 1) {
|
||||
if((serial.charAt(1) == 0) || (serial.charAt(1) == 1) || (serial.charAt(1) == 3)) {
|
||||
if((serial.charAt(3) == 1) || (serial.charAt(3) == 2) || (serial.charAt(3) == 4)) {
|
||||
switch(serial.charAt(2)) {
|
||||
default:
|
||||
case "2": max = 1; break;
|
||||
case "4": max = 2; break;
|
||||
case "6": max = 4; break;
|
||||
case "8": max = 6; break;
|
||||
var nrf = true;
|
||||
switch(sn & 0xff00) {
|
||||
case 0x1000: nrf = true; break;
|
||||
case 0x1100:
|
||||
switch(sn & 0x000f) {
|
||||
case 0x0004: nrf = false; break;
|
||||
default: nrf = true; break;
|
||||
}
|
||||
break;
|
||||
case 0x1300: nrf = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < max; i++) {
|
||||
setHide("ch"+i, false);
|
||||
}
|
||||
setHide("setcmt", nrf);
|
||||
setHide("setnrf", !nrf);
|
||||
document.getElementsByName("isnrf")[0].value = nrf;
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -728,6 +777,11 @@
|
|||
q.yld = document.getElementsByName("yld_c"+i)[0].value;
|
||||
o.ch.push(q);
|
||||
}
|
||||
if("true" == document.getElementsByName("isnrf")[0].value)
|
||||
o.pa = document.getElementsByName("nrfpa")[0].value;
|
||||
else
|
||||
o.pa = document.getElementsByName("cmtpa")[0].value;
|
||||
o.freq = document.getElementsByName("freq")[0].value;
|
||||
getAjax("/api/setup", cb, "POST", JSON.stringify(o));
|
||||
}
|
||||
|
||||
|
@ -845,19 +899,6 @@
|
|||
])
|
||||
);
|
||||
}
|
||||
e.append(
|
||||
ml("div", {class: "row mb-3"}, [
|
||||
ml("div", {class: "col-12 col-sm-3 my-2"}, "Power Level"),
|
||||
ml("div", {class: "col-12 col-sm-9"},
|
||||
sel("rf24Power", [
|
||||
[0, "MIN (recommended)"],
|
||||
[1, "LOW"],
|
||||
[2, "HIGH"],
|
||||
[3, "MAX (experimental)"]
|
||||
], obj["power_level"])
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*IF_ESP32*/
|
||||
|
|
|
@ -686,7 +686,7 @@ div.hr {
|
|||
margin: 1.75rem auto;
|
||||
}
|
||||
|
||||
.modal {
|
||||
.modal, #modal-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
@ -695,6 +695,10 @@ div.hr {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.modal {
|
||||
height: calc(100% - 3.5rem);
|
||||
}
|
||||
|
||||
#modal-wrapper {
|
||||
background-color: #000;
|
||||
opacity: 0.5;
|
||||
|
@ -710,6 +714,8 @@ div.hr {
|
|||
background-clip: padding-box;
|
||||
border: 1px solid var(--fg);
|
||||
flex-direction: column;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
|
@ -717,7 +723,7 @@ div.hr {
|
|||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
border-bottom: 1px solid var(--table-border);
|
||||
}
|
||||
|
||||
.modal-header .close {
|
||||
|
@ -726,7 +732,8 @@ div.hr {
|
|||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 1rem 1rem 2rem 1rem;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.close {
|
||||
|
@ -779,3 +786,41 @@ h5 {
|
|||
vertical-align: baseline;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid var(--fg);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
margin-bottom: -1px;
|
||||
border: 1px solid transparent;
|
||||
border-top-left-radius: .25rem;
|
||||
border-top-right-radius: .25rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: block;
|
||||
padding: .5rem 1rem;
|
||||
text-decoration: none;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
border-color: var(--fg) var(--fg) var(--bg);
|
||||
}
|
||||
|
||||
.nav-link:hover, .nav-link:visited {
|
||||
background-color: var(--input-bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
|
|
@ -45,13 +45,11 @@
|
|||
}
|
||||
|
||||
function parseRadio(obj) {
|
||||
const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"];
|
||||
const dr = ["1 M", "2 M", "250 k"]
|
||||
|
||||
if(obj.radioNrf.en) {
|
||||
lines = [
|
||||
tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "not ") + "connected")),
|
||||
tr("NRF24 Power Level", pa[obj.radioNrf.power_level]),
|
||||
tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps")
|
||||
];
|
||||
} else
|
||||
|
|
|
@ -519,8 +519,6 @@ class Web {
|
|||
}
|
||||
}
|
||||
|
||||
// nrf24 amplifier power
|
||||
mConfig->nrf.amplifierPower = request->arg("rf24Power").toInt() & 0x03;
|
||||
mConfig->nrf.enabled = (request->arg("nrfEnable") == "on");
|
||||
|
||||
// cmt
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue