Browse Source

Merge pull request #361 from DanielR92/dev03

app.cpp make nicer readable and shorten if statements
pull/373/head
Lukas Pusch 2 years ago
committed by GitHub
parent
commit
2af55cb685
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      tools/esp8266/.vscode/settings.json
  2. 186
      tools/esp8266/app.cpp
  3. 2
      tools/esp8266/platformio.ini
  4. 6
      tools/rpi/hoymiles/__main__.py

23
tools/esp8266/.vscode/settings.json

@ -0,0 +1,23 @@
// Place your settings in this file to overwrite default and user settings.
{
// identify that settings is loaded
"workbench.colorCustomizations": {
"editorLineNumber.foreground": "#00ff00"
},
"editor.wordWrap": "off",
"files.eol" : "\n",
"files.trimTrailingWhitespace" : true,
"diffEditor.ignoreTrimWhitespace": true,
"files.autoSave": "afterDelay",
"editor.tabSize": 4,
"editor.insertSpaces": true,
// `editor.tabSize` and `editor.insertSpaces` will be detected based on the file contents.
// Set to false to keep the values you've explicitly set, above.
"editor.detectIndentation": false,
// https://clang.llvm.org/docs/ClangFormatStyleOptions.html
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 0}",
}

186
tools/esp8266/app.cpp

@ -9,8 +9,8 @@
#endif
#include "app.h"
#include <ArduinoJson.h>
#include <ArduinoJson.h>
//-----------------------------------------------------------------------------
app::app() {
@ -27,7 +27,6 @@ app::app() {
mShouldReboot = false;
}
//-----------------------------------------------------------------------------
void app::setup(uint32_t timeout) {
DPRINTLN(DBG_VERBOSE, F("app::setup"));
@ -82,7 +81,6 @@ void app::loop(void) {
ESP.restart();
}
mSys->Radio.loop();
yield();
@ -100,24 +98,26 @@ void app::loop(void) {
DPRINT(DBG_INFO, "RX " + String(len) + "B Ch" + String(p->rxCh) + " | ");
mSys->Radio.dumpBuf(NULL, p->packet, len);
}
mStat.frmCnt++;
if (0 != len) {
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
if((NULL != iv) && (p->packet[0] == (TX_REQ_INFO + 0x80))) { // response from get information command
if ((NULL != iv) && (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES))) // response from get information command
{
mPayload[iv->id].txId = p->packet[0];
DPRINTLN(DBG_DEBUG, F("Response from info request received"));
uint8_t *pid = &p->packet[9];
if (*pid == 0x00)
DPRINT(DBG_DEBUG, "fragment number zero received and ignored");
else {
if (*pid == 0x00) {
DPRINT(DBG_DEBUG, F("fragment number zero received and ignored"));
} else {
DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX));
if ((*pid & 0x7F) < 5) {
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], len - 11);
mPayload[iv->id].len[(*pid & 0x7F) - 1] = len - 11;
}
if ((*pid & 0x80) == 0x80) {
if ((*pid & ALL_FRAMES) == ALL_FRAMES) {
// Last packet
if ((*pid & 0x7f) > mPayload[iv->id].maxPackId) {
mPayload[iv->id].maxPackId = (*pid & 0x7f);
@ -127,15 +127,16 @@ void app::loop(void) {
}
}
}
if((NULL != iv) && (p->packet[0] == (TX_REQ_DEVCONTROL + 0x80))) { // response from dev control command
mPayload[iv->id].txId = p->packet[0];
if ((NULL != iv) && (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES))) // response from dev control command
{
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
mPayload[iv->id].txId = p->packet[0];
iv->devControlRequest = false;
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]));
String msg = (p->packet[10] == 0x00 && p->packet[11] == 0x00) ? "" : "NOT ";
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
}
iv->devControlCmd = Init;
}
@ -145,7 +146,6 @@ void app::loop(void) {
}
yield();
if (rxRdy) {
processPayload(true);
}
@ -267,6 +267,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) {
if (mConfig.serialDebug)
DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
@ -274,30 +275,26 @@ void app::loop(void) {
mPayload[iv->id].txCmd = iv->devControlCmd;
iv->clearCmdQueue();
iv->enqueCommand<InfoCommand>(SystemConfigPara);
}
else {
} else {
uint8_t cmd = iv->getQueuedCmd();
mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex);
mPayload[iv->id].txCmd = cmd;
mRxTicker = 0;
}
}
}
else if(mConfig.serialDebug)
} else if (mConfig.serialDebug)
DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!"));
yield();
}
}
}
//-----------------------------------------------------------------------------
void app::handleIntr(void) {
DPRINTLN(DBG_VERBOSE, F("app::handleIntr"));
mSys->Radio.handleIntr();
}
//-----------------------------------------------------------------------------
bool app::buildPayload(uint8_t id) {
DPRINTLN(DBG_VERBOSE, F("app::buildPayload"));
@ -309,23 +306,18 @@ bool app::buildPayload(uint8_t id) {
if (mPayload[id].len[i] > 0) {
if (i == (mPayload[id].maxPackId - 1)) {
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc);
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8)
| (mPayload[id].data[i][mPayload[id].len[i] - 1]);
}
else
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]);
} else
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc);
}
yield();
}
if(crc == crcRcv)
return true;
return false;
}
return (crc == crcRcv) ? true : false;
}
//-----------------------------------------------------------------------------
void app::processPayload(bool retransmit) {
#ifdef __MQTT_AFTER_RX__
boolean doMQTT = false;
#endif
@ -334,14 +326,15 @@ void app::processPayload(bool retransmit) {
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
Inverter<> *iv = mSys->getInverterByPos(id);
if (NULL != iv) {
if((mPayload[iv->id].txId != (TX_REQ_INFO + 0x80)) && (0 != mPayload[iv->id].txId)) {
if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) {
// no processing needed if txId is not 0x95
// DPRINTLN(DBG_INFO, F("processPayload - set complete, txId: ") + String(mPayload[iv->id].txId, HEX));
mPayload[iv->id].complete = true;
}
if (!mPayload[iv->id].complete) {
if(!buildPayload(iv->id)) { // payload not complete
if (!buildPayload(iv->id)) // payload not complete
{
if (mPayload[iv->id].requested) {
if (retransmit) {
if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) {
@ -361,8 +354,7 @@ void app::processPayload(bool retransmit) {
}
yield();
}
}
else {
} else {
if (mConfig.serialDebug)
DPRINTLN(DBG_WARN, F("while retrieving data: last frame missing: Request Retransmit"));
if (0x00 != mLastPacketId)
@ -377,8 +369,7 @@ void app::processPayload(bool retransmit) {
}
}
}
}
else { // payload complete
} else { // payload complete
DPRINTLN(DBG_INFO, F("procPyld: cmd: ") + String(mPayload[iv->id].txCmd));
DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX));
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
@ -402,9 +393,9 @@ void app::processPayload(bool retransmit) {
mSys->Radio.dumpBuf(NULL, payload, payloadLen);
}
if(NULL == rec)
if (NULL == rec) {
DPRINTLN(DBG_ERROR, F("record is NULL!"));
else if((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
} else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
if (mPayload[iv->id].txId == (TX_REQ_INFO + 0x80))
mStat.rxSuccess++;
@ -432,10 +423,18 @@ void app::processPayload(bool retransmit) {
if (recRealtime == rec) {
if (CH0 == rec->assign[i].ch) {
switch (rec->assign[i].fieldId) {
case FLD_PAC: total[0] += iv->getValue(i, rec); break;
case FLD_YT: total[1] += iv->getValue(i, rec); break;
case FLD_YD: total[2] += iv->getValue(i, rec); break;
case FLD_PDC: total[3] += iv->getValue(i, rec); break;
case FLD_PAC:
total[0] += iv->getValue(i, rec);
break;
case FLD_YT:
total[1] += iv->getValue(i, rec);
break;
case FLD_YD:
total[2] += iv->getValue(i, rec);
break;
case FLD_PDC:
total[3] += iv->getValue(i, rec);
break;
}
}
}
@ -444,18 +443,19 @@ void app::processPayload(bool retransmit) {
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
snprintf(val, 32, DEF_MQTT_IV_MESSAGE_INVERTER_AVAIL_AND_PRODUCED);
mMqtt.sendMsg(topic, val);
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->name);
snprintf(val, 32, "2");
mMqtt.sendMsg(topic, val);
} else {
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
snprintf(val, 32, DEF_MQTT_IV_MESSAGE_INVERTER_AVAIL_AND_NOT_PRODUCED);
mMqtt.sendMsg(topic, val);
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->name);
snprintf(val, 32, "1");
mMqtt.sendMsg(topic, val);
}
mMqtt.sendMsg(topic, val);
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->name);
snprintf(val, 48, "%i", iv->getLastTs(rec) * 1000);
mMqtt.sendMsg(topic, val);
@ -472,10 +472,18 @@ void app::processPayload(bool retransmit) {
uint8_t fieldId = 0;
for (uint8_t i = 0; i < 4; i++) {
switch (i) {
case 0: fieldId = FLD_PAC; break;
case 1: fieldId = FLD_YT; break;
case 2: fieldId = FLD_YD; break;
case 3: fieldId = FLD_PDC; break;
case 0:
fieldId = FLD_PAC;
break;
case 1:
fieldId = FLD_YT;
break;
case 2:
fieldId = FLD_YD;
break;
case 3:
fieldId = FLD_PDC;
break;
}
snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
snprintf(val, 10, "%.3f", total[i]);
@ -484,8 +492,7 @@ void app::processPayload(bool retransmit) {
}
}
}
}
else {
} else {
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
mStat.rxFail++;
}
@ -514,7 +521,6 @@ void app::processPayload(bool retransmit) {
#endif
}
//-----------------------------------------------------------------------------
void app::cbMqtt(char *topic, byte *payload, unsigned int length) {
// callback handling on subscribed devcontrol topic
@ -522,18 +528,21 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
// subcribed topics are mTopic + "/devcontrol/#" where # is <inverter_id>/<subcmd in dec>
// eg. mypvsolar/devcontrol/1/11 with payload "400" --> inverter 1 active power limit 400 Watt
const char *token = strtok(topic, "/");
while (token != NULL)
{
while (token != NULL) {
if (strcmp(token, "devcontrol") == 0) {
token = strtok(NULL, "/");
uint8_t iv_id = std::stoi(token);
if (iv_id >= 0 && iv_id <= MAX_NUM_INVERTERS) {
Inverter<> *iv = this->mSys->getInverterByPos(iv_id);
if (NULL != iv) {
if (!iv->devControlRequest) { // still pending
if (!iv->devControlRequest) // still pending
{
token = strtok(NULL, "/");
switch (std::stoi(token)) {
case ActivePowerContr: // Active Power Control
// Active Power Control
case ActivePowerContr:
token = strtok(NULL, "/"); // get ControlMode aka "PowerPF.Desc" in DTU-Pro Code from topic string
if (token == NULL) // default via mqtt ommit the LimitControlMode
iv->powerLimit[1] = AbsolutNonPersistent;
@ -543,32 +552,42 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
if (iv->powerLimit[1] >= AbsolutNonPersistent && iv->powerLimit[1] <= RelativPersistent) {
iv->devControlCmd = ActivePowerContr;
iv->powerLimit[0] = std::stoi(std::string((char *)payload, (unsigned int)length)); // THX to @silversurfer
if (iv->powerLimit[1] & 0x0001)
/*if (iv->powerLimit[1] & 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 for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W"));*/
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F((iv->powerLimit[1] & 0x0001) ? "%" : "W"));
}
iv->devControlRequest = true;
} else {
DPRINTLN(DBG_INFO, F("Invalid mqtt payload recevied: ") + String((char *)payload));
}
break;
case TurnOn: // Turn On
// Turn On
case TurnOn:
iv->devControlCmd = TurnOn;
DPRINTLN(DBG_INFO, F("Turn on inverter ") + String(iv->id));
iv->devControlRequest = true;
break;
case TurnOff: // Turn Off
// Turn Off
case TurnOff:
iv->devControlCmd = TurnOff;
DPRINTLN(DBG_INFO, F("Turn off inverter ") + String(iv->id));
iv->devControlRequest = true;
break;
case Restart: // Restart
// Restart
case Restart:
iv->devControlCmd = Restart;
DPRINTLN(DBG_INFO, F("Restart inverter ") + String(iv->id));
iv->devControlRequest = true;
break;
case ReactivePowerContr: // Reactive Power Control
// Reactive Power Control
case ReactivePowerContr:
iv->devControlCmd = ReactivePowerContr;
if (true) { // if (std::stoi((char*)payload) > 0) error handling powerlimit needed?
iv->devControlCmd = ReactivePowerContr;
@ -578,16 +597,21 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
iv->devControlRequest = true;
}
break;
case PFSet: // Set Power Factor
// Set Power Factor
case PFSet:
// iv->devControlCmd = PFSet;
// uint16_t power_factor = std::stoi(strtok(NULL, "/"));
DPRINTLN(DBG_INFO, F("Set Power Factor not implemented for inverter ") + String(iv->id));
break;
case CleanState_LockAndAlarm: // CleanState lock & alarm
// CleanState lock & alarm
case CleanState_LockAndAlarm:
iv->devControlCmd = CleanState_LockAndAlarm;
DPRINTLN(DBG_INFO, F("CleanState lock & alarm for inverter ") + String(iv->id));
iv->devControlRequest = true;
break;
default:
DPRINTLN(DBG_INFO, "Not implemented");
break;
@ -602,13 +626,11 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
DPRINTLN(DBG_INFO, F("app::cbMqtt finished"));
}
//-----------------------------------------------------------------------------
bool app::getWifiApActive(void) {
return mWifi->getApActive();
}
//-----------------------------------------------------------------------------
void app::scanAvailNetworks(void) {
mWifi->scanAvailNetworks();
@ -620,7 +642,6 @@ void app::getAvailNetworks(JsonObject obj) {
mWifi->getAvailNetworks(obj);
}
//-----------------------------------------------------------------------------
void app::sendMqttDiscoveryConfig(void) {
DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig"));
@ -679,7 +700,6 @@ void app::sendMqttDiscoveryConfig(void) {
}
}
//-----------------------------------------------------------------------------
const char *app::getFieldDeviceClass(uint8_t fieldId) {
uint8_t pos = 0;
@ -690,7 +710,6 @@ const char* app::getFieldDeviceClass(uint8_t fieldId) {
return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : deviceClasses[deviceFieldAssignment[pos].deviceClsId];
}
//-----------------------------------------------------------------------------
const char *app::getFieldStateClass(uint8_t fieldId) {
uint8_t pos = 0;
@ -701,7 +720,6 @@ const char* app::getFieldStateClass(uint8_t fieldId) {
return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId];
}
//-----------------------------------------------------------------------------
void app::resetSystem(void) {
mUptimeSecs = 0;
@ -733,13 +751,11 @@ void app::resetSystem(void) {
mShowRebootRequest = false;
memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t)));
memset(&mStat, 0, sizeof(statistics_t));
mLastPacketId = 0x00;
}
//-----------------------------------------------------------------------------
void app::loadDefaultConfig(void) {
memset(&mSysConfig, 0, sizeof(sysConfig_t));
@ -752,7 +768,6 @@ void app::loadDefaultConfig(void) {
snprintf(mSysConfig.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID);
snprintf(mSysConfig.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD);
// nrf24
mConfig.sendInterval = SEND_INTERVAL;
mConfig.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD;
@ -786,7 +801,6 @@ void app::loadDefaultConfig(void) {
mConfig.disclaimer = false;
}
//-----------------------------------------------------------------------------
void app::loadEEpconfig(void) {
DPRINTLN(DBG_VERBOSE, F("app::loadEEpconfig"));
@ -829,7 +843,6 @@ void app::loadEEpconfig(void) {
}
}
//-----------------------------------------------------------------------------
void app::saveValues(void) {
DPRINTLN(DBG_VERBOSE, F("app::saveValues"));
@ -854,43 +867,26 @@ void app::saveValues(void) {
mLatestSunTimestamp = 0;
}
//-----------------------------------------------------------------------------
void app::setupMqtt(void) {
if (mSettingsValid) {
if (mConfig.mqtt.broker[0] > 0) {
mMqttActive = true;
if(mMqttInterval < MIN_MQTT_INTERVAL)
mMqttInterval = MIN_MQTT_INTERVAL;
}
else
if (mMqttInterval < MIN_MQTT_INTERVAL) mMqttInterval = MIN_MQTT_INTERVAL;
} else {
mMqttInterval = 0xffff;
}
mMqttTicker = 0;
mMqtt.setup(&mConfig.mqtt, mSysConfig.deviceName);
mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
if (mMqttActive) {
mMqtt.sendMsg("version", mVersion);
if (mMqtt.isConnected()) {
mMqtt.sendMsg("device", mSysConfig.deviceName);
mMqtt.sendMsg("uptime", "0");
}
/*char topic[30];
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
iv = mSys->getInverterByPos(i);
if(NULL != iv) {
for(uint8_t i = 0; i < 4; i++) {
if(0 != iv->chName[i][0]) {
snprintf(topic, 30, "%s/ch%d/%s", iv->name, i+1, "name");
mMqtt.sendMsg(topic, iv->chName[i]);
yield();
}
}
}
}*/
}
}
}

2
tools/esp8266/platformio.ini

@ -69,7 +69,6 @@ platform = espressif32
board = lolin_d32
build_flags = -D RELEASE -std=gnu++14
build_unflags = -std=gnu++11
upload_port = /dev/cu.SLAB_USBtoUART
monitor_filters =
;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line
@ -81,7 +80,6 @@ board = lolin_d32
build_flags = -DDEBUG_LEVEL=DBG_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_OOM -DDEBUG_ESP_PORT=Serial -std=gnu++14
build_unflags = -std=gnu++11
build_type = debug
upload_port = /dev/cu.SLAB_USBtoUART
monitor_filters =
;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line

6
tools/rpi/hoymiles/__main__.py

@ -322,8 +322,10 @@ if __name__ == '__main__':
print('', end='', flush=True)
if loop_interval > 0 and (time.time() - t_loop_start) < loop_interval:
time.sleep(loop_interval - (time.time() - t_loop_start))
time_to_sleep = loop_interval - (time.time() - t_loop_start)
if loop_interval > 0 and time_to_sleep > 0:
time.sleep(time_to_sleep)
except KeyboardInterrupt:
sys.exit()

Loading…
Cancel
Save