mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-24 22:36:10 +02:00
added regex to inverter name and MQTT topic (setup.html)
beautified serial.html added ticker for wifi loop #515 reverted sunrise / sunset ticker to most recent version
This commit is contained in:
parent
c71975a164
commit
6bb8a4e448
11 changed files with 76 additions and 42 deletions
|
@ -1,5 +1,10 @@
|
|||
# Changelog
|
||||
|
||||
## 0.5.60
|
||||
* added regex to inverter name and MQTT topic (setup.html)
|
||||
* beautified serial.html
|
||||
* added ticker for wifi loop #515
|
||||
|
||||
## 0.5.59
|
||||
* fix night communication enable
|
||||
* improved different WiFi connection scenarios (STA WiFi not found, reconnect #509, redirect for AP to configuration)
|
||||
|
|
14
src/app.cpp
14
src/app.cpp
|
@ -41,8 +41,11 @@ void app::setup() {
|
|||
#endif
|
||||
|
||||
mWifi.setup(mConfig, &mTimestamp);
|
||||
#if !defined(AP_ONLY)
|
||||
everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi));
|
||||
#endif
|
||||
|
||||
every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval);
|
||||
mSendTickerId = every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval);
|
||||
#if !defined(AP_ONLY)
|
||||
once(std::bind(&app::tickNtpUpdate, this), 2);
|
||||
#endif
|
||||
|
@ -78,6 +81,7 @@ void app::setup() {
|
|||
|
||||
mPubSerial.setup(mConfig, mSys, &mTimestamp);
|
||||
every(std::bind(&PubSerialType::tick, &mPubSerial), mConfig->serial.interval);
|
||||
//everySec(std::bind(&app::tickSerial, this));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -85,11 +89,6 @@ void app::loop(void) {
|
|||
DPRINTLN(DBG_VERBOSE, F("app::loop"));
|
||||
|
||||
ah::Scheduler::loop();
|
||||
|
||||
#if !defined(AP_ONLY)
|
||||
mWifi.loop();
|
||||
#endif
|
||||
|
||||
mSys->Radio.loop();
|
||||
|
||||
yield();
|
||||
|
@ -142,7 +141,7 @@ void app::tickCalcSunrise(void) {
|
|||
ah::calculateSunriseSunset(mTimestamp, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset);
|
||||
tickIVCommunication();
|
||||
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight, -10 for safety that it is certain next day
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 10) % 86400) + 86400; // next midnight, -10 for safety that it is certain next day
|
||||
onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig);
|
||||
if (mConfig->mqtt.broker[0] > 0) {
|
||||
mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec, mConfig->sun.disNightCom);
|
||||
|
@ -263,6 +262,7 @@ void app::resetSystem(void) {
|
|||
mSunset = 0;
|
||||
|
||||
mRxTicker = 0;
|
||||
mSendTickerId = 0xff; // invalid id
|
||||
|
||||
mSendLastIvId = 0;
|
||||
mShowRebootRequest = false;
|
||||
|
|
15
src/app.h
15
src/app.h
|
@ -191,6 +191,20 @@ class app : public IApp, public ah::Scheduler {
|
|||
void tickCalcSunrise(void);
|
||||
void tickIVCommunication(void);
|
||||
void tickSend(void);
|
||||
/*void tickSerial(void) {
|
||||
if(Serial.available() == 0)
|
||||
return;
|
||||
|
||||
uint8_t buf[80];
|
||||
uint8_t len = Serial.readBytes(buf, 80);
|
||||
DPRINTLN(DBG_INFO, "got serial data, len: " + String(len));
|
||||
for(uint8_t i = 0; i < len; i++) {
|
||||
if((0 != i) && (i % 8 == 0))
|
||||
DBGPRINTLN("");
|
||||
DBGPRINT(String(buf[i], HEX) + " ");
|
||||
}
|
||||
DBGPRINTLN("");
|
||||
}*/
|
||||
|
||||
bool mShowRebootRequest;
|
||||
bool mIVCommunicationOn;
|
||||
|
@ -206,6 +220,7 @@ class app : public IApp, public ah::Scheduler {
|
|||
settings_t *mConfig;
|
||||
|
||||
uint8_t mSendLastIvId;
|
||||
uint8_t mSendTickerId;
|
||||
|
||||
statistics_t mStat;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 59
|
||||
#define VERSION_PATCH 60
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -11,7 +11,7 @@ struct node_s {
|
|||
typedef T dT;
|
||||
node_s *pre;
|
||||
node_s *nxt;
|
||||
uint32_t id;
|
||||
uint8_t id;
|
||||
dT d;
|
||||
node_s() : pre(NULL), nxt(NULL), d() {}
|
||||
node_s(Args... args) : id(0), pre(NULL), nxt(NULL), d(args...) {}
|
||||
|
|
|
@ -72,8 +72,8 @@ namespace ah {
|
|||
}
|
||||
|
||||
void once(scdCb c, uint32_t timeout) { mStack.add(c, timeout, 0); }
|
||||
void every(scdCb c, uint32_t interval) { mStack.add(c, interval, interval); }
|
||||
void onceAt(scdCb c, uint32_t timestamp) { mStackAt.add(c, timestamp); }
|
||||
uint8_t every(scdCb c, uint32_t interval){ return mStack.add(c, interval, interval)->id; }
|
||||
|
||||
void everySec(scdCb c) { mStack.add(c, SCD_SEC, SCD_SEC); }
|
||||
void everyMin(scdCb c) { mStack.add(c, SCD_MIN, SCD_MIN); }
|
||||
|
@ -85,6 +85,20 @@ namespace ah {
|
|||
mTimestamp = ts;
|
||||
}
|
||||
|
||||
bool resetEveryById(uint8_t id) {
|
||||
sP *p = mStack.getFront();
|
||||
while(NULL != p) {
|
||||
if(p->id == id)
|
||||
break;
|
||||
p = mStack.get(p);
|
||||
}
|
||||
if(NULL != p) {
|
||||
p->d.timeout = p->d.reload;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t getUptime(void) {
|
||||
return mUptime;
|
||||
}
|
||||
|
@ -135,7 +149,7 @@ namespace ah {
|
|||
}
|
||||
}
|
||||
|
||||
llist<25, scdEvry_s, scdCb, uint32_t, uint32_t> mStack;
|
||||
llist<20, scdEvry_s, scdCb, uint32_t, uint32_t> mStack;
|
||||
llist<10, scdAt_s, scdCb, uint32_t> mStackAt;
|
||||
uint32_t mMillis, mPrevMillis, mDiff;
|
||||
uint32_t mUptime;
|
||||
|
|
|
@ -129,7 +129,7 @@ function lbl(htmlfor, val, cl=null, id=null) {
|
|||
return e;
|
||||
}
|
||||
|
||||
function inp(name, val, max=32, cl=["text"], id=null, type=null) {
|
||||
function inp(name, val, max=32, cl=["text"], id=null, type=null, pattern=null, title=null) {
|
||||
e = document.createElement('input');
|
||||
e.classList.add(...cl);
|
||||
e.name = name;
|
||||
|
@ -137,6 +137,8 @@ function inp(name, val, max=32, cl=["text"], id=null, type=null) {
|
|||
if(null != max) e.maxLength = max;
|
||||
if(null != id) e.id = id;
|
||||
if(null != type) e.type = type;
|
||||
if(null != pattern) e.pattern = pattern;
|
||||
if(null != title) e.title = title;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,21 +25,11 @@
|
|||
Uptime: <span id="uptime"></span>
|
||||
<input type="button" value="clear" class="btn" id="clear"/>
|
||||
<input type="button" value="autoscroll" class="btn" id="scroll"/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<hr>
|
||||
<div class="hr mt-3 mb-3"></div>
|
||||
<h3>Commands</h3>
|
||||
<br/>
|
||||
<label for="iv">Select Inverter:</label>
|
||||
<select name="iv" id="InvID">
|
||||
</select>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<label for="pwrlimval">Power Limit Value</label>
|
||||
<input type="number" class="text" name="pwrlimval" maxlength="4"/>
|
||||
<label for="pwrlimctrl">Power Limit Command</label>
|
||||
|
@ -52,8 +42,8 @@
|
|||
</select>
|
||||
<br/>
|
||||
<input type="button" value="Send Power Limit" class="btn" id="sendpwrlim"/>
|
||||
<br/>
|
||||
<div id="power">
|
||||
<div class="hr mt-3 mb-3"></div>
|
||||
<div id="power" class="mt-3">
|
||||
<input type="button" value="Restart" class="btn" id="restart"/>
|
||||
<input type="button" value="Turn Off" class="btn" id="power_off"/>
|
||||
<input type="button" value="Turn On" class="btn" id="power_on"/>
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
<label for="mqttPwd">Password (optional)</label>
|
||||
<input type="password" class="text" name="mqttPwd"/>
|
||||
<label for="mqttTopic">Topic</label>
|
||||
<input type="text" class="text" name="mqttTopic"/>
|
||||
<input type="text" class="text" name="mqttTopic" pattern="[A-Za-z0-9.-_]+" title="Invalid input" />
|
||||
<label for="mqttBtn">Discovery Config (homeassistant)</label>
|
||||
<input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/>
|
||||
<span id="apiResultMqtt"></span>
|
||||
|
@ -165,11 +165,15 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="reboot">Reboot device after successful save</label>
|
||||
<input type="checkbox" class="cb" name="reboot" checked />
|
||||
<input type="submit" value="save" class="btn right"/><br/>
|
||||
<br/>
|
||||
<input type="submit" value="save" class="btn right"/>
|
||||
</div>
|
||||
<div class="hr mb-3 mt-3"></div>
|
||||
<div class="mb-4">
|
||||
<a href="/get_setup" target="_blank">Download your settings (JSON file)</a> (only saved values)
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -305,28 +309,31 @@
|
|||
})
|
||||
});
|
||||
|
||||
for(var i of [["Name", "name", "Name*", 32]]) {
|
||||
iv.appendChild(lbl(id + i[0], i[2]));
|
||||
iv.appendChild(inp(id + i[0], obj[i[1]], i[3]));
|
||||
}
|
||||
iv.append(
|
||||
lbl(id + "Name", "Name*"),
|
||||
inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9.-_]+", "Invalid input")
|
||||
);
|
||||
|
||||
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4], ["ModName", "ch_name", "Module Name", 16]]) {
|
||||
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"], ["ModName", "ch_name", "Module Name", 16, "[A-Za-z0-9.-_]+"]]) {
|
||||
var cl = (re.test(obj["serial"])) ? null : ["hide"];
|
||||
iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0]));
|
||||
d = div([j[0]]);
|
||||
i = 0;
|
||||
cl = (re.test(obj["serial"])) ? ["text", "sh"] : ["text", "sh", "hide"];
|
||||
for(it of obj[j[1]]) {
|
||||
d.appendChild(inp(id + j[0] + i, it, j[3], cl, id + j[0] + i));
|
||||
d.appendChild(inp(id + j[0] + i, it, j[3], cl, id + j[0] + i, "text", j[4], "Invalid input"));
|
||||
i++;
|
||||
}
|
||||
iv.appendChild(d);
|
||||
}
|
||||
iv.appendChild(br());
|
||||
iv.appendChild(lbl(id + "lbldel", "Delete"));
|
||||
|
||||
var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button");
|
||||
iv.appendChild(del);
|
||||
del.addEventListener("click", delIv);
|
||||
iv.append(
|
||||
br(),
|
||||
lbl(id + "lbldel", "Delete"),
|
||||
del
|
||||
);
|
||||
}
|
||||
|
||||
function ivGlob(obj) {
|
||||
|
|
|
@ -59,7 +59,7 @@ void ahoywifi::setupWifi(void) {
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ahoywifi::loop() {
|
||||
void ahoywifi::tickWifiLoop() {
|
||||
#if !defined(AP_ONLY)
|
||||
if(mReconnect) {
|
||||
delay(100);
|
||||
|
@ -132,6 +132,7 @@ void ahoywifi::setupStation(void) {
|
|||
mReconnect = (WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd) != WL_CONNECTED);
|
||||
if(String(mConfig->sys.deviceName) != "")
|
||||
WiFi.hostname(mConfig->sys.deviceName);
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
|
||||
DBGPRINT(F("connect to network '"));
|
||||
DBGPRINT(mConfig->sys.stationSsid);
|
||||
|
|
|
@ -21,7 +21,7 @@ class ahoywifi {
|
|||
ahoywifi();
|
||||
|
||||
void setup(settings_t *config, uint32_t *utcTimestamp);
|
||||
void loop(void);
|
||||
void tickWifiLoop(void);
|
||||
bool getNtpTime(void);
|
||||
void scanAvailNetworks(void);
|
||||
void getAvailNetworks(JsonObject obj);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue