Browse Source

changed sunrise / sunset calculation, angle is now `-3.5` instead of original `-0.83`

improved scheduler (removed -1 from `reload`) #483
improved reboot flag in `app.h`
fixed #493 no MQTT payload once display is defined
pull/518/head
lumapu 2 years ago
parent
commit
ea6a9c155c
  1. 6
      src/CHANGES.md
  2. 23
      src/app.cpp
  3. 32
      src/app.h
  4. 2
      src/defines.h
  5. 19
      src/hm/hmInverter.h
  6. 2
      src/hm/hmRadio.h
  7. 4
      src/publisher/pubMqtt.h
  8. 2
      src/utils/helper.cpp
  9. 2
      src/utils/scheduler.h
  10. 2
      src/utils/sun.h
  11. 8
      src/web/RestApi.h
  12. 21
      src/web/html/serial.html

6
src/CHANGES.md

@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.5.54
* changed sunrise / sunset calculation, angle is now `-3.5` instead of original `-0.83`
* improved scheduler (removed -1 from `reload`) #483
* improved reboot flag in `app.h`
* fixed #493 no MQTT payload once display is defined
## 0.5.53 ## 0.5.53
* Mono-Display: show values in offline mode #498 * Mono-Display: show values in offline mode #498
* improved wifi class #483 * improved wifi class #483

23
src/app.cpp

@ -30,8 +30,6 @@ void app::setup() {
mSettings.getPtr(mConfig); mSettings.getPtr(mConfig);
DPRINTLN(DBG_INFO, F("Settings valid: ") + String((mSettings.getValid()) ? F("true") : F("false"))); DPRINTLN(DBG_INFO, F("Settings valid: ") + String((mSettings.getValid()) ? F("true") : F("false")));
everySec(std::bind(&app::tickSecond, this));
every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval); every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval);
#if !defined(AP_ONLY) #if !defined(AP_ONLY)
once(std::bind(&app::tickNtpUpdate, this), 2); once(std::bind(&app::tickNtpUpdate, this), 2);
@ -44,6 +42,8 @@ void app::setup() {
mSys = new HmSystemType(); mSys = new HmSystemType();
mSys->enableDebug(); mSys->enableDebug();
mSys->setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs); mSys->setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs);
mPayload.addListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1));
#if !defined(AP_ONLY) #if !defined(AP_ONLY)
mMqtt.setup(&mConfig->mqtt, mConfig->sys.deviceName, mVersion, mSys, &mTimestamp, &mSunrise, &mSunset); mMqtt.setup(&mConfig->mqtt, mConfig->sys.deviceName, mVersion, mSys, &mTimestamp, &mSunrise, &mSunset);
@ -62,7 +62,6 @@ void app::setup() {
// when WiFi is in client mode, then enable mqtt broker // when WiFi is in client mode, then enable mqtt broker
#if !defined(AP_ONLY) #if !defined(AP_ONLY)
if (mConfig->mqtt.broker[0] > 0) { if (mConfig->mqtt.broker[0] > 0) {
mPayload.addListener(std::bind(&PubMqttType::payloadEventListener, &mMqtt, std::placeholders::_1));
everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt)); everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt));
everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt)); everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt));
mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1)); mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1));
@ -75,19 +74,10 @@ void app::setup() {
everySec(std::bind(&WebType::tickSecond, &mWeb)); everySec(std::bind(&WebType::tickSecond, &mWeb));
mApi.setup(this, mSys, mWeb.getWebSrvPtr(), mConfig); mApi.setup(this, mSys, mWeb.getWebSrvPtr(), mConfig);
/*mApi.registerCb(apiCbScanNetworks, std::bind(&app::scanAvailNetworks, this));
#if !defined(AP_ONLY)
mApi.registerCb(apiCbMqttTxCnt, std::bind(&PubMqttType::getTxCnt, &mMqtt));
mApi.registerCb(apiCbMqttRxCnt, std::bind(&PubMqttType::getRxCnt, &mMqtt));
mApi.registerCb(apiCbMqttIsCon, std::bind(&PubMqttType::isConnected, &mMqtt));
mApi.registerCb(apiCbMqttDiscvry, std::bind(&PubMqttType::sendDiscoveryConfig, &mMqtt));
//mApi.registerCb(apiCbMqttDiscvry, std::bind(&app::setMqttDiscoveryFlag, this));
#endif*/
// Plugins // Plugins
#if defined(ENA_NOKIA) || defined(ENA_SSD1306) #if defined(ENA_NOKIA) || defined(ENA_SSD1306)
mMonoDisplay.setup(mSys, &mTimestamp); mMonoDisplay.setup(mSys, &mTimestamp);
mPayload.addListener(std::bind(&MonoDisplayType::payloadEventListener, &mMonoDisplay, std::placeholders::_1));
everySec(std::bind(&MonoDisplayType::tickerSecond, &mMonoDisplay)); everySec(std::bind(&MonoDisplayType::tickerSecond, &mMonoDisplay));
#endif #endif
@ -107,11 +97,6 @@ void app::loop(void) {
mWeb.loop(); mWeb.loop();
if (mFlagSendDiscoveryConfig) {
mFlagSendDiscoveryConfig = false;
mMqtt.sendDiscoveryConfig();
}
mSys->Radio.loop(); mSys->Radio.loop();
yield(); yield();
@ -253,10 +238,6 @@ void app::handleIntr(void) {
void app::resetSystem(void) { void app::resetSystem(void) {
snprintf(mVersion, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); snprintf(mVersion, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
mShouldReboot = false;
mUpdateNtp = false;
mFlagSendDiscoveryConfig = false;
#ifdef AP_ONLY #ifdef AP_ONLY
mTimestamp = 1; mTimestamp = 1;
#else #else

32
src/app.h

@ -94,7 +94,7 @@ class app : public IApp, public ah::Scheduler {
} }
void setRebootFlag() { void setRebootFlag() {
mShouldReboot = true; once(std::bind(&app::tickReboot, this), 1);
} }
const char *getVersion() { const char *getVersion() {
@ -118,7 +118,7 @@ class app : public IApp, public ah::Scheduler {
} }
void setMqttDiscoveryFlag() { void setMqttDiscoveryFlag() {
mFlagSendDiscoveryConfig = true; once(std::bind(&PubMqttType::sendDiscoveryConfig, &mMqtt), 1);
} }
bool getMqttIsConnected() { bool getMqttIsConnected() {
@ -153,32 +153,33 @@ class app : public IApp, public ah::Scheduler {
void setTimestamp(uint32_t newTime) { void setTimestamp(uint32_t newTime) {
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime)); DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
if(0 == newTime) if(0 == newTime)
mUpdateNtp = true; mWifi.getNtpTime();
else else
Scheduler::setTimestamp(newTime); Scheduler::setTimestamp(newTime);
} }
HmSystemType *mSys; HmSystemType *mSys;
bool mShouldReboot;
private: private:
void resetSystem(void); void resetSystem(void);
void payloadEventListener(uint8_t cmd) {
#if !defined(AP_ONLY)
mMqtt.payloadEventListener(cmd);
#endif
#if defined(ENA_NOKIA) || defined(ENA_SSD1306)
mMonoDisplay.payloadEventListener(cmd);
#endif
}
void mqttSubRxCb(JsonObject obj); void mqttSubRxCb(JsonObject obj);
void setupLed(void); void setupLed(void);
void updateLed(void); void updateLed(void);
void tickSecond(void) { void tickReboot(void) {
if (mShouldReboot) { DPRINTLN(DBG_INFO, F("Rebooting..."));
DPRINTLN(DBG_INFO, F("Rebooting...")); ESP.restart();
ESP.restart();
}
if (mUpdateNtp) {
mUpdateNtp = false;
mWifi.getNtpTime();
}
} }
void tickNtpUpdate(void); void tickNtpUpdate(void);
@ -206,9 +207,6 @@ class app : public IApp, public ah::Scheduler {
DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag)); DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag));
} }
bool mUpdateNtp;
bool mFlagSendDiscoveryConfig;
bool mShowRebootRequest; bool mShowRebootRequest;
ahoywifi mWifi; ahoywifi mWifi;

2
src/defines.h

@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 5 #define VERSION_MINOR 5
#define VERSION_PATCH 53 #define VERSION_PATCH 54
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

19
src/hm/hmInverter.h

@ -109,7 +109,6 @@ class Inverter {
uint8_t id; // unique id uint8_t id; // unique id
uint8_t type; // integer which refers to inverter type uint8_t type; // integer which refers to inverter type
uint16_t alarmMesIndex; // Last recorded Alarm Message Index uint16_t alarmMesIndex; // Last recorded Alarm Message Index
uint16_t fwVersion; // Firmware Version from Info Command Request
uint16_t powerLimit[2]; // limit power output uint16_t powerLimit[2]; // limit power output
float actPowerLimit; // actual power limit float actPowerLimit; // actual power limit
uint8_t devControlCmd; // carries the requested cmd uint8_t devControlCmd; // carries the requested cmd
@ -130,7 +129,6 @@ class Inverter {
devControlRequest = false; devControlRequest = false;
devControlCmd = InitDataState; devControlCmd = InitDataState;
initialized = false; initialized = false;
fwVersion = 0;
lastAlarmMsg = "nothing"; lastAlarmMsg = "nothing";
alarmMesIndex = 0; alarmMesIndex = 0;
} }
@ -153,6 +151,7 @@ class Inverter {
} }
void clearCmdQueue() { void clearCmdQueue() {
DPRINTLN(DBG_INFO, F("clearCmdQueue"));
while (!_commandQueue.empty()) { while (!_commandQueue.empty()) {
// Will destroy CommandAbstract Class Object (?) // Will destroy CommandAbstract Class Object (?)
_commandQueue.pop(); _commandQueue.pop();
@ -161,7 +160,7 @@ class Inverter {
uint8_t getQueuedCmd() { uint8_t getQueuedCmd() {
if (_commandQueue.empty()) { if (_commandQueue.empty()) {
if (fwVersion == 0) if (getFwVersion() == 0)
enqueCommand<InfoCommand>(InverterDevInform_All); enqueCommand<InfoCommand>(InverterDevInform_All);
enqueCommand<InfoCommand>(RealTimeRunData_Debug); enqueCommand<InfoCommand>(RealTimeRunData_Debug);
if (actPowerLimit == 0xffff) if (actPowerLimit == 0xffff)
@ -264,11 +263,7 @@ class Inverter {
} }
else if (rec->assign == InfoAssignment) { else if (rec->assign == InfoAssignment) {
DPRINTLN(DBG_DEBUG, "add info"); DPRINTLN(DBG_DEBUG, "add info");
// get at least the firmware version and save it to the inverter object // eg. fw version ...
if (getPosByChFld(0, FLD_FW_VERSION, rec) == pos){
fwVersion = rec->record[pos];
DPRINT(DBG_DEBUG, F("Inverter FW-Version: ") + String(fwVersion));
}
} }
else if (rec->assign == SystemConfigParaAssignment) { else if (rec->assign == SystemConfigParaAssignment) {
DPRINTLN(DBG_DEBUG, "add config"); DPRINTLN(DBG_DEBUG, "add config");
@ -295,6 +290,8 @@ class Inverter {
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getValue")); DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getValue"));
if(NULL == rec) if(NULL == rec)
return 0; return 0;
if(pos > rec->length)
return 0;
return rec->record[pos]; return rec->record[pos];
} }
@ -323,6 +320,12 @@ class Inverter {
return false; return false;
} }
uint16_t getFwVersion() {
record_t<> *rec = getRecordStruct(InverterDevInform_All);
uint8_t pos = getPosByChFld(CH0, FLD_FW_VERSION, rec);
return getValue(pos, rec);
}
uint32_t getLastTs(record_t<> *rec) { uint32_t getLastTs(record_t<> *rec) {
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getLastTs")); DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getLastTs"));
return rec->ts; return rec->ts;

2
src/hm/hmRadio.h

@ -221,7 +221,7 @@ class HmRadio {
} }
void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) { void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) {
DPRINTLN(DBG_VERBOSE, F("sendTimePacket")); DPRINTLN(DBG_INFO, F("sendTimePacket ") + String(cmd, HEX));
sendCmdPacket(invId, TX_REQ_INFO, ALL_FRAMES, false); sendCmdPacket(invId, TX_REQ_INFO, ALL_FRAMES, false);
mTxBuf[10] = cmd; // cid mTxBuf[10] = cmd; // cid
mTxBuf[11] = 0x00; mTxBuf[11] = 0x00;

4
src/publisher/pubMqtt.h

@ -140,8 +140,8 @@ class PubMqtt {
if(!mClient.connected()) if(!mClient.connected())
return; return;
char topic[MQTT_TOPIC_LEN + 2]; char topic[(MQTT_TOPIC_LEN << 1) + 2];
snprintf(topic, (MQTT_TOPIC_LEN + 2), "%s/%s", mCfgMqtt->topic, subTopic); snprintf(topic, ((MQTT_TOPIC_LEN << 1) + 2), "%s/%s", mCfgMqtt->topic, subTopic);
if(addTopic) if(addTopic)
mClient.publish(topic, QOS_0, retained, payload); mClient.publish(topic, QOS_0, retained, payload);
else else

2
src/utils/helper.cpp

@ -9,7 +9,7 @@ namespace ah {
void ip2Arr(uint8_t ip[], const char *ipStr) { void ip2Arr(uint8_t ip[], const char *ipStr) {
memset(ip, 0, 4); memset(ip, 0, 4);
char *tmp = new char[strlen(ipStr)+1]; char *tmp = new char[strlen(ipStr)+1];
strncpy(tmp, ipStr, strlen(ipStr)+1); snprintf(tmp, strlen(ipStr), ipStr);
char *p = strtok(tmp, "."); char *p = strtok(tmp, ".");
uint8_t i = 0; uint8_t i = 0;
while(NULL != p) { while(NULL != p) {

2
src/utils/scheduler.h

@ -111,7 +111,7 @@ namespace ah {
if(0 == p->d.reload) if(0 == p->d.reload)
p = mStack.rem(p); p = mStack.rem(p);
else { else {
p->d.timeout = p->d.reload - 1; p->d.timeout = p->d.reload;
p = mStack.get(p); p = mStack.get(p);
} }
} }

2
src/utils/sun.h

@ -25,7 +25,7 @@ namespace ah {
// Declination of the sun // Declination of the sun
double delta = ASIN(SIN(lambda) * SIN(23.44)); double delta = ASIN(SIN(lambda) * SIN(23.44));
// Hour angle // Hour angle
double omega = ACOS((SIN(-0.83) - SIN(lat) * SIN(delta)) / (COS(lat) * COS(delta))); double omega = ACOS((SIN(-3.5) - SIN(lat) * SIN(delta)) / (COS(lat) * COS(delta))); //(SIN(-0.83)
// Calculate sunrise and sunset // Calculate sunrise and sunset
double Jrise = Jtransit - omega / 360; double Jrise = Jtransit - omega / 360;
double Jset = Jtransit + omega / 360; double Jset = Jtransit + omega / 360;

8
src/web/RestApi.h

@ -251,7 +251,7 @@ class RestApi {
obj2[F("name")] = String(iv->config->name); obj2[F("name")] = String(iv->config->name);
obj2[F("serial")] = String(iv->config->serial.u64, HEX); obj2[F("serial")] = String(iv->config->serial.u64, HEX);
obj2[F("channels")] = iv->channels; obj2[F("channels")] = iv->channels;
obj2[F("version")] = String(iv->fwVersion); obj2[F("version")] = String(iv->getFwVersion());
for(uint8_t j = 0; j < iv->channels; j ++) { for(uint8_t j = 0; j < iv->channels; j ++) {
obj2[F("ch_max_power")][j] = iv->config->chMaxPwr[j]; obj2[F("ch_max_power")][j] = iv->config->chMaxPwr[j];
@ -357,7 +357,7 @@ class RestApi {
invObj[F("enabled")] = (bool)iv->config->enabled; invObj[F("enabled")] = (bool)iv->config->enabled;
invObj[F("id")] = i; invObj[F("id")] = i;
invObj[F("name")] = String(iv->config->name); invObj[F("name")] = String(iv->config->name);
invObj[F("version")] = String(iv->fwVersion); invObj[F("version")] = String(iv->getFwVersion());
invObj[F("is_avail")] = iv->isAvailable(mApp->getTimestamp(), rec); invObj[F("is_avail")] = iv->isAvailable(mApp->getTimestamp(), rec);
invObj[F("is_producing")] = iv->isProducing(mApp->getTimestamp(), rec); invObj[F("is_producing")] = iv->isProducing(mApp->getTimestamp(), rec);
invObj[F("ts_last_success")] = iv->getLastTs(rec); invObj[F("ts_last_success")] = iv->getLastTs(rec);
@ -501,6 +501,10 @@ class RestApi {
iv->devControlCmd = ActivePowerContr; iv->devControlCmd = ActivePowerContr;
iv->devControlRequest = true; iv->devControlRequest = true;
} }
else if(F("dev") == jsonIn[F("cmd")]) {
DPRINTLN(DBG_INFO, F("dev cmd"));
iv->enqueCommand<InfoCommand>(jsonIn[F("val")].as<int>());
}
else { else {
jsonOut[F("error")] = F("unknown cmd: '") + jsonIn["cmd"].as<String>() + "'"; jsonOut[F("error")] = F("unknown cmd: '") + jsonIn["cmd"].as<String>() + "'";
return false; return false;

21
src/web/html/serial.html

@ -35,12 +35,6 @@
<select name="iv" id="InvID"> <select name="iv" id="InvID">
</select> </select>
<br/> <br/>
<div id="power">
<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"/>
</div>
<br/>
<br/> <br/>
<br/> <br/>
<br/> <br/>
@ -58,6 +52,13 @@
<br/> <br/>
<input type="button" value="Send Power Limit" class="btn" id="sendpwrlim"/> <input type="button" value="Send Power Limit" class="btn" id="sendpwrlim"/>
<br/> <br/>
<div id="power">
<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"/>
<input type="button" value="Alarm Info" class="btn" id="alarminfo"/>
</div>
<br/>
<p>Ctrl result: <span id="result">n/a</span></p> <p>Ctrl result: <span id="result">n/a</span></p>
</div> </div>
</div> </div>
@ -185,6 +186,14 @@
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj)); getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
}); });
document.getElementById("alarminfo").addEventListener("click", function() {
var obj = new Object();
obj.id = get_selected_iv();
obj.cmd = "dev";
obj.val = 0x11;
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
});
document.getElementById("sendpwrlim").addEventListener("click", function() { document.getElementById("sendpwrlim").addEventListener("click", function() {
var val = parseInt(document.getElementsByName('pwrlimval')[0].value); var val = parseInt(document.getElementsByName('pwrlimval')[0].value);
var cmd = document.getElementsByName('pwrlimctrl')[0].value; var cmd = document.getElementsByName('pwrlimctrl')[0].value;

Loading…
Cancel
Save