mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 07:26:38 +02:00
0.5.14 Bug fix mqtt payload & get FWVersion
Changes 0.5.14. - bug fix in mqtt payload handling thx to @klahus1 and silversurfer - small improvements in code styling - refactoring to get have the option to implement different parse for InfoCommands - Get FWVersion by REST API call - Display FWVersion in webui (only after REST API call)
This commit is contained in:
parent
16d348dc0b
commit
3e1b120b74
7 changed files with 160 additions and 110 deletions
|
@ -84,6 +84,29 @@ void app::loop(void) {
|
|||
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
||||
if(NULL != iv && p->packet[0] == (TX_REQ_INFO + 0x80)) { // response from get information command
|
||||
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 & 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)
|
||||
{ // Last packet
|
||||
if ((*pid & 0x7f) > mPayload[iv->id].maxPackId)
|
||||
{
|
||||
mPayload[iv->id].maxPackId = (*pid & 0x7f);
|
||||
if (*pid > 0x81)
|
||||
mLastPacketId = *pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (mSys->InfoCmd){
|
||||
case InverterDevInform_Simple:
|
||||
{
|
||||
|
@ -94,7 +117,6 @@ void app::loop(void) {
|
|||
case InverterDevInform_All:
|
||||
{
|
||||
DPRINT(DBG_INFO, "Response from inform all\n");
|
||||
mSys->InfoCmd = RealTimeRunData_Debug; // Set back to default
|
||||
break;
|
||||
}
|
||||
case GetLossRate:
|
||||
|
@ -117,23 +139,6 @@ void app::loop(void) {
|
|||
}
|
||||
case RealTimeRunData_Debug:
|
||||
{
|
||||
uint8_t *pid = &p->packet[9];
|
||||
if (*pid == 0x00) {
|
||||
DPRINT(DBG_DEBUG, "fragment number zero received and ignored");
|
||||
} else {
|
||||
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) { // Last packet
|
||||
if((*pid & 0x7f) > mPayload[iv->id].maxPackId) {
|
||||
mPayload[iv->id].maxPackId = (*pid & 0x7f);
|
||||
if(*pid > 0x81)
|
||||
mLastPacketId = *pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +180,7 @@ void app::loop(void) {
|
|||
|
||||
|
||||
if(rxRdy) {
|
||||
processPayload(true);
|
||||
processPayload(true,mSys->InfoCmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +266,7 @@ void app::loop(void) {
|
|||
|
||||
if(NULL != iv) {
|
||||
if(!mPayload[iv->id].complete)
|
||||
processPayload(false);
|
||||
processPayload(false,mSys->InfoCmd);
|
||||
|
||||
if(!mPayload[iv->id].complete) {
|
||||
mRxFailed++;
|
||||
|
@ -271,13 +276,7 @@ void app::loop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// reset payload data
|
||||
memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||
mPayload[iv->id].retransmits = 0;
|
||||
mPayload[iv->id].maxPackId = 0;
|
||||
mPayload[iv->id].complete = false;
|
||||
mPayload[iv->id].requested = true;
|
||||
mPayload[iv->id].ts = mTimestamp;
|
||||
resetPayload(iv);
|
||||
|
||||
yield();
|
||||
if(mConfig.serialDebug)
|
||||
|
@ -335,6 +334,9 @@ bool app::buildPayload(uint8_t id) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::processPayload(bool retransmit) {
|
||||
processPayload(retransmit, RealTimeRunData_Debug);
|
||||
}
|
||||
void app::processPayload(bool retransmit, uint8_t cmd = RealTimeRunData_Debug) { // cmd value decides which parser is used to decode payload
|
||||
|
||||
#ifdef __MQTT_AFTER_RX__
|
||||
boolean doMQTT = false;
|
||||
|
@ -390,12 +392,14 @@ void app::processPayload(bool retransmit) {
|
|||
mSys->Radio.dumpBuf(NULL, payload, offs);
|
||||
}
|
||||
mRxSuccess++;
|
||||
mSys->InfoCmd = RealTimeRunData_Debug; // On success set back to default
|
||||
|
||||
iv->getAssignment(cmd); // choose the parser
|
||||
for(uint8_t i = 0; i < iv->listLen; i++) {
|
||||
iv->addValue(i, payload);
|
||||
iv->addValue(i, payload,cmd); // cmd value decides which parser is used to decode payload
|
||||
yield();
|
||||
}
|
||||
iv->doCalculations();
|
||||
iv->doCalculations(cmd); // cmd value decides which parser is used to decode payload
|
||||
|
||||
#ifdef __MQTT_AFTER_RX__
|
||||
doMQTT = true;
|
||||
|
@ -444,12 +448,10 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
|
|||
iv->powerLimit[1] = AbsolutNonPersistent;
|
||||
else
|
||||
iv->powerLimit[1] = std::stoi(token);
|
||||
DPRINTLN(DBG_VERBOSE, F("iv->powerLimit[1]=") + String(iv->powerLimit[1]));
|
||||
DPRINTLN(DBG_VERBOSE, F("length=") + String(length));
|
||||
if (length<=5){ // if (std::stoi((char*)payload) > 0) more error handling powerlimit needed?
|
||||
if (iv->powerLimit[1] >= AbsolutNonPersistent && iv->powerLimit[1] <= RelativPersistent){
|
||||
iv->devControlCmd = ActivePowerContr;
|
||||
iv->powerLimit[0] = std::stoi((char*)payload);
|
||||
iv->powerLimit[0] = std::stoi(std::string((char*)payload, (unsigned int)length)); // THX to @silversurfer
|
||||
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
|
||||
|
@ -517,7 +519,7 @@ String app::getStatistics(void) {
|
|||
iv = mSys->getInverterByPos(i);
|
||||
if(NULL != iv) {
|
||||
bool avail = true;
|
||||
content += F("Inverter '") + String(iv->name) + F("' is ");
|
||||
content += F("Inverter '") + String(iv->name) + F(" (FW-Version: ") + String(iv->fwVersion) +F(")") + F("' is ");
|
||||
if(!iv->isAvailable(mTimestamp)) {
|
||||
content += F("not ");
|
||||
avail = false;
|
||||
|
@ -936,3 +938,15 @@ void app::setupMqtt(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::resetPayload(Inverter<>* iv)
|
||||
{
|
||||
// reset payload data
|
||||
memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||
mPayload[iv->id].retransmits = 0;
|
||||
mPayload[iv->id].maxPackId = 0;
|
||||
mPayload[iv->id].complete = false;
|
||||
mPayload[iv->id].requested = true;
|
||||
mPayload[iv->id].ts = mTimestamp;
|
||||
}
|
|
@ -69,6 +69,7 @@ class app {
|
|||
void handleIntr(void);
|
||||
void cbMqtt(char* topic, byte* payload, unsigned int length);
|
||||
void saveValues(void);
|
||||
void resetPayload(Inverter<>* iv);
|
||||
String getStatistics(void);
|
||||
String getLiveData(void);
|
||||
String getJson(void);
|
||||
|
@ -150,6 +151,7 @@ class app {
|
|||
|
||||
bool buildPayload(uint8_t id);
|
||||
void processPayload(bool retransmit);
|
||||
void processPayload(bool retransmit, uint8_t cmd);
|
||||
|
||||
void sendMqttDiscoveryConfig(void);
|
||||
const char* getFieldDeviceClass(uint8_t fieldId);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 13
|
||||
#define VERSION_PATCH 14
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
|
|
@ -17,15 +17,15 @@ union serial_u {
|
|||
|
||||
|
||||
// units
|
||||
enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VA, UNIT_ALARM_MES_ID};
|
||||
enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VA, UNIT_NONE};
|
||||
const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%","VAr",""};
|
||||
|
||||
|
||||
// field types
|
||||
enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT,
|
||||
FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PCT, FLD_EFF, FLD_IRR, FLD_PRA,FLD_ALARM_MES_ID};
|
||||
FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PCT, FLD_EFF, FLD_IRR, FLD_PRA,FLD_ALARM_MES_ID,FLD_FW_VERSION,FLD_FW_BUILD_YEAR,FLD_FW_BUILD_MONTH_DAY,FLD_HW_ID};
|
||||
const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal",
|
||||
"U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct", "Efficiency", "Irradiation","P_ACr","ALARM_MES_ID"};
|
||||
"U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct", "Efficiency", "Irradiation","P_ACr","ALARM_MES_ID","FWVersion","FWBuildYear","FWBuildMonthDay","HWPartId"};
|
||||
|
||||
// mqtt discovery device classes
|
||||
enum {DEVICE_CLS_NONE = 0, DEVICE_CLS_CURRENT, DEVICE_CLS_ENERGY, DEVICE_CLS_PWR, DEVICE_CLS_VOLTAGE, DEVICE_CLS_FREQ, DEVICE_CLS_TEMP};
|
||||
|
@ -81,6 +81,19 @@ typedef struct {
|
|||
* (complete payload in buffer)
|
||||
* */
|
||||
|
||||
//-------------------------------------
|
||||
// HM-Series
|
||||
//-------------------------------------
|
||||
const byteAssign_t InfoAssignment[] = {
|
||||
{ FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
|
||||
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
|
||||
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
|
||||
{ FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 }
|
||||
};
|
||||
#define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t))
|
||||
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
// HM300, HM350, HM400
|
||||
//-------------------------------------
|
||||
|
@ -98,7 +111,7 @@ const byteAssign_t hm1chAssignment[] = {
|
|||
{ FLD_PRA, UNIT_VA, CH0, 20, 2, 10 },
|
||||
{ FLD_F, UNIT_HZ, CH0, 16, 2, 100 },
|
||||
{ FLD_T, UNIT_C, CH0, 26, 2, 10 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 28, 2, 1 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 28, 2, 1 },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
};
|
||||
|
@ -129,7 +142,7 @@ const byteAssign_t hm2chAssignment[] = {
|
|||
{ FLD_PRA, UNIT_VA, CH0, 32, 2, 10 },
|
||||
{ FLD_F, UNIT_HZ, CH0, 28, 2, 100 },
|
||||
{ FLD_T, UNIT_C, CH0, 38, 2, 10 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 40, 2, 1 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 40, 2, 1 },
|
||||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
|
@ -178,7 +191,7 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_F, UNIT_HZ, CH0, 48, 2, 100 },
|
||||
{ FLD_PCT, UNIT_PCT, CH0, 56, 2, 10 },
|
||||
{ FLD_T, UNIT_C, CH0, 58, 2, 10 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 60, 2, 1 },
|
||||
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 60, 2, 1 },
|
||||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
|
|
|
@ -70,6 +70,7 @@ class Inverter {
|
|||
byteAssign_t* assign; // type of inverter
|
||||
uint8_t listLen; // length of assignments
|
||||
uint16_t alarmMesIndex; // Last recorded Alarm Message Index
|
||||
uint16_t fwVersion; // Firmware Version from Info Command Request
|
||||
uint16_t powerLimit[2]; // limit power output
|
||||
uint8_t devControlCmd; // carries the requested cmd
|
||||
bool devControlRequest; // true if change needed
|
||||
|
@ -87,6 +88,7 @@ class Inverter {
|
|||
powerLimit[1] = 0x0000; //
|
||||
devControlRequest = false;
|
||||
devControlCmd = 0xff;
|
||||
fwVersion = 0;
|
||||
}
|
||||
|
||||
~Inverter() {
|
||||
|
@ -128,7 +130,7 @@ class Inverter {
|
|||
return assign[pos].ch;
|
||||
}
|
||||
|
||||
void addValue(uint8_t pos, uint8_t buf[]) {
|
||||
void addValue(uint8_t pos, uint8_t buf[],uint8_t cmd) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue"));
|
||||
uint8_t ptr = assign[pos].start;
|
||||
uint8_t end = ptr + assign[pos].num;
|
||||
|
@ -142,19 +144,30 @@ class Inverter {
|
|||
|
||||
record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||
}
|
||||
// get last alarm message index and save it in the inverter instance
|
||||
if (cmd == RealTimeRunData_Debug) {
|
||||
// get last alarm message index and save it in the inverter object
|
||||
if (getPosByChFld(0, FLD_ALARM_MES_ID) == pos){
|
||||
alarmMesIndex = record[pos];
|
||||
}
|
||||
}
|
||||
if (cmd == InverterDevInform_All) {
|
||||
// get at least the firmware version and save it to the inverter object
|
||||
if (getPosByChFld(0, FLD_FW_VERSION) == pos){
|
||||
fwVersion = record[pos];
|
||||
DPRINT(DBG_DEBUG, F("Inverter FW-Version: ") + String(fwVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RECORDTYPE getValue(uint8_t pos) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getValue"));
|
||||
return record[pos];
|
||||
}
|
||||
|
||||
void doCalculations(void) {
|
||||
void doCalculations(uint8_t cmd=RealTimeRunData_Debug) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:doCalculations"));
|
||||
getAssignment(cmd);
|
||||
if (cmd == RealTimeRunData_Debug){
|
||||
for(uint8_t i = 0; i < listLen; i++) {
|
||||
if(CMD_CALC == assign[i].div) {
|
||||
record[i] = calcFunctions<RECORDTYPE>[assign[i].start].func(this, assign[i].num);
|
||||
|
@ -162,6 +175,7 @@ class Inverter {
|
|||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isAvailable(uint32_t timestamp) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:isAvailable"));
|
||||
|
@ -182,19 +196,9 @@ class Inverter {
|
|||
return ts;
|
||||
}
|
||||
|
||||
private:
|
||||
void toRadioId(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:toRadioId"));
|
||||
radioId.u64 = 0ULL;
|
||||
radioId.b[4] = serial.b[0];
|
||||
radioId.b[3] = serial.b[1];
|
||||
radioId.b[2] = serial.b[2];
|
||||
radioId.b[1] = serial.b[3];
|
||||
radioId.b[0] = 0x01;
|
||||
}
|
||||
|
||||
void getAssignment(void) {
|
||||
void getAssignment(uint8_t cmd=RealTimeRunData_Debug) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getAssignment"));
|
||||
if(cmd == RealTimeRunData_Debug){
|
||||
if(INV_TYPE_1CH == type) {
|
||||
listLen = (uint8_t)(HM1CH_LIST_LEN);
|
||||
assign = (byteAssign_t*)hm1chAssignment;
|
||||
|
@ -216,6 +220,22 @@ class Inverter {
|
|||
assign = NULL;
|
||||
}
|
||||
}
|
||||
if(cmd == InverterDevInform_All){
|
||||
listLen = (uint8_t)(HMINFO_LIST_LEN);
|
||||
assign = (byteAssign_t*)InfoAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void toRadioId(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:toRadioId"));
|
||||
radioId.u64 = 0ULL;
|
||||
radioId.b[4] = serial.b[0];
|
||||
radioId.b[3] = serial.b[1];
|
||||
radioId.b[2] = serial.b[2];
|
||||
radioId.b[1] = serial.b[3];
|
||||
radioId.b[0] = 0x01;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -164,20 +164,10 @@ class HmRadio {
|
|||
mTxBuf[10] = cmd; // cmd --> 0x0b => Type_ActivePowerContr, 0 on, 1 off, 2 restart, 12 reactive power, 13 power factor
|
||||
mTxBuf[10 + (++cnt)] = 0x00;
|
||||
if (cmd >= ActivePowerContr && cmd <= PFSet){
|
||||
// 4 bytes control data
|
||||
// Power Limit fix point 10 eg. 30 W --> 0d300 = 0x012c
|
||||
// -1 = 0xffff --> no limit
|
||||
uint16_t powerLimit = data[0];
|
||||
uint16_t powerLimitSetting = data[1];
|
||||
if (powerLimit == 0xffff){
|
||||
powerLimit &= 0xffff; // ToDo: unlimit value is needed and is inverter specific! --> get it via RF from inverter or via user interface
|
||||
} else {
|
||||
powerLimit *= 10; // will overwrite the data bc it is a pointer
|
||||
}
|
||||
mTxBuf[10 + (++cnt)] = (powerLimit >> 8) & 0xff; // power limit
|
||||
mTxBuf[10 + (++cnt)] = (powerLimit ) & 0xff; // power limit
|
||||
mTxBuf[10 + (++cnt)] = (powerLimitSetting >> 8) & 0xff; // setting for persistens handling
|
||||
mTxBuf[10 + (++cnt)] = (powerLimitSetting ) & 0xff; // setting for persistens handling
|
||||
mTxBuf[10 + (++cnt)] = ((data[0] * 10) >> 8) & 0xff; // power limit
|
||||
mTxBuf[10 + (++cnt)] = ((data[0] * 10) ) & 0xff; // power limit
|
||||
mTxBuf[10 + (++cnt)] = ((data[1] ) >> 8) & 0xff; // setting for persistens handlings
|
||||
mTxBuf[10 + (++cnt)] = ((data[1] ) ) & 0xff; // setting for persistens handling
|
||||
}
|
||||
// crc control data
|
||||
uint16_t crc = crc16(&mTxBuf[10], cnt+1);
|
||||
|
|
|
@ -417,9 +417,9 @@ void web::showJson(void) {
|
|||
mWeb->send(200, F("application/json"), mMain->getJson());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void web::showWebApi(void) {
|
||||
void web::showWebApi(void)
|
||||
{
|
||||
DPRINTLN(DBG_VERBOSE, F("web::showWebApi"));
|
||||
DPRINTLN(DBG_DEBUG, mWeb->arg("plain"));
|
||||
const size_t capacity = 200; // Use arduinojson.org/assistant to compute the capacity.
|
||||
|
@ -429,39 +429,50 @@ void web::showWebApi(void) {
|
|||
deserializeJson(response, mWeb->arg("plain"));
|
||||
// ToDo: error handling for payload
|
||||
uint8_t iv_id = response["inverter"];
|
||||
if (response["tx_request"] == (uint8_t)TX_REQ_INFO) {
|
||||
mMain->mSys->InfoCmd = response["cmd"];
|
||||
if (mMain->mSys->InfoCmd == AlarmData){
|
||||
Inverter<> *iv = mMain->mSys->getInverterByPos(iv_id);
|
||||
if (NULL != iv){
|
||||
if (NULL != iv)
|
||||
{
|
||||
if (response["tx_request"] == (uint8_t)TX_REQ_INFO)
|
||||
{
|
||||
mMain->mSys->InfoCmd = response["cmd"];
|
||||
mMain->resetPayload(iv); // start request from new
|
||||
// process payload from web request corresponding to the cmd
|
||||
if (mMain->mSys->InfoCmd == AlarmData)
|
||||
iv->alarmMesIndex = response["payload"];
|
||||
}
|
||||
}
|
||||
DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(mMain->mSys->InfoCmd) + F(" and payload ") + String(response["payload"]));
|
||||
}
|
||||
if (response["tx_request"] == (uint8_t)TX_REQ_DEVCONTROL){
|
||||
if(response["cmd"] == (uint8_t)ActivePowerContr){
|
||||
if (iv_id >= 0 && iv_id <= MAX_NUM_INVERTERS){
|
||||
Inverter<> *iv = mMain->mSys->getInverterByPos(iv_id);
|
||||
|
||||
|
||||
if (response["tx_request"] == (uint8_t)TX_REQ_DEVCONTROL)
|
||||
{
|
||||
if (response["cmd"] == (uint8_t)ActivePowerContr)
|
||||
{
|
||||
uint16_t webapiPayload = response["payload"];
|
||||
uint16_t webapiPayload2 = response["payload2"];
|
||||
if (webapiPayload > 0 && webapiPayload < 10000){
|
||||
if (webapiPayload > 0 && webapiPayload < 10000)
|
||||
{
|
||||
iv->devControlCmd = ActivePowerContr;
|
||||
iv->powerLimit[0] = webapiPayload;
|
||||
if (webapiPayload2 > 0){
|
||||
if (webapiPayload2 > 0)
|
||||
{
|
||||
iv->powerLimit[1] = webapiPayload2; // dev option, no sanity check
|
||||
} else { // if not set, set it to 0x0000 default
|
||||
}
|
||||
else
|
||||
{ // if not set, set it to 0x0000 default
|
||||
iv->powerLimit[1] = AbsolutNonPersistent; // payload will be seted temporay in Watt absolut
|
||||
}
|
||||
if (iv->powerLimit[1] & 0x0001 ){
|
||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("% via REST API") );
|
||||
} else {
|
||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W via REST API") );
|
||||
if (iv->powerLimit[1] & 0x0001)
|
||||
{
|
||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("% via REST API"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W via REST API"));
|
||||
}
|
||||
iv->devControlRequest = true; // queue it in the request loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mWeb->send ( 200, "text/json", "{success:true}" );
|
||||
mWeb->send(200, "text/json", "{success:true}");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue