* optimize API authentication, Error-Codes #1415
* breaking change: authentication API command changed #1415
* breaking change: limit has to be send als `float`, `0.0 .. 100.0` #1415
* updated documentation #1415
* fix don't send control command twice #1426
This commit is contained in:
lumapu 2024-02-12 22:32:13 +01:00
parent 315541ea51
commit 31232bfd80
10 changed files with 116 additions and 70 deletions

View file

@ -30,10 +30,6 @@
#define F(sl) (sl)
#endif
const uint8_t acList[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
const uint8_t acListHmt[] = {FLD_UAC_1N, FLD_IAC_1, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
const uint8_t dcList[] = {FLD_UDC, FLD_IDC, FLD_PDC, FLD_YD, FLD_YT, FLD_IRR, FLD_MP};
template<class HMSYSTEM>
class RestApi {
public:
@ -831,14 +827,16 @@ class RestApi {
}
bool setCtrl(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) {
if(F("auth") == jsonIn[F("cmd")]) {
if(String(jsonIn["val"]) == String(mConfig->sys.adminPwd))
jsonOut["token"] = mApp->unlock(clientIP, false);
else {
jsonOut[F("error")] = F(AUTH_ERROR);
if(jsonIn.containsKey(F("auth"))) {
if(String(jsonIn[F("auth")]) == String(mConfig->sys.adminPwd)) {
jsonOut[F("token")] = mApp->unlock(clientIP, false);
jsonIn[F("token")] = jsonOut[F("token")];
} else {
jsonOut[F("error")] = F("ERR_AUTH");
return false;
}
return true;
if(!jsonIn.containsKey(F("cmd")))
return true;
}
if(isProtected(jsonIn, jsonOut, clientIP))
@ -847,7 +845,7 @@ class RestApi {
Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")]);
bool accepted = true;
if(NULL == iv) {
jsonOut[F("error")] = F(INV_INDEX_INVALID) + jsonIn[F("id")].as<String>();
jsonOut[F("error")] = F("ERR_INDEX");
return false;
}
jsonOut[F("id")] = jsonIn[F("id")];
@ -857,7 +855,7 @@ class RestApi {
else if(F("restart") == jsonIn[F("cmd")])
accepted = iv->setDevControlRequest(Restart);
else if(0 == strncmp("limit_", jsonIn[F("cmd")].as<const char*>(), 6)) {
iv->powerLimit[0] = jsonIn["val"];
iv->powerLimit[0] = static_cast<uint16_t>(jsonIn["val"].as<float>() * 10.0);
if(F("limit_persistent_relative") == jsonIn[F("cmd")])
iv->powerLimit[1] = RelativPersistent;
else if(F("limit_persistent_absolute") == jsonIn[F("cmd")])
@ -874,12 +872,12 @@ class RestApi {
DPRINTLN(DBG_INFO, F("dev cmd"));
iv->setDevCommand(jsonIn[F("val")].as<int>());
} else {
jsonOut[F("error")] = F(UNKNOWN_CMD) + jsonIn["cmd"].as<String>() + "'";
jsonOut[F("error")] = F("ERR_UNKNOWN_CMD");
return false;
}
if(!accepted) {
jsonOut[F("error")] = F(INV_DOES_NOT_ACCEPT_LIMIT_AT_MOMENT);
jsonOut[F("error")] = F("ERR_LIMIT_NOT_ACCEPT");
return false;
}
@ -930,7 +928,7 @@ class RestApi {
iv->config->disNightCom = jsonIn[F("disnightcom")];
mApp->saveSettings(false); // without reboot
} else {
jsonOut[F("error")] = F(UNKNOWN_CMD);
jsonOut[F("error")] = F("ERR_UNKNOWN_CMD");
return false;
}
@ -947,7 +945,7 @@ class RestApi {
if(!mApp->isProtected(clientIP, token, false))
return false;
jsonOut[F("error")] = F(IS_PROTECTED);
jsonOut[F("error")] = F("ERR_PROTECTED");
return true;
}
}
@ -955,6 +953,13 @@ class RestApi {
return false;
}
private:
constexpr static uint8_t acList[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT,
FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
constexpr static uint8_t acListHmt[] = {FLD_UAC_1N, FLD_IAC_1, FLD_PAC, FLD_F, FLD_PF, FLD_T,
FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
constexpr static uint8_t dcList[] = {FLD_UDC, FLD_IDC, FLD_PDC, FLD_YD, FLD_YT, FLD_IRR, FLD_MP};
private:
IApp *mApp = nullptr;
HMSYSTEM *mSys = nullptr;

View file

@ -22,6 +22,15 @@
var total = Array(6).fill(0);
var tPwrAck;
function getErrStr(code) {
if("ERR_AUTH") return "{#ERR_AUTH}"
if("ERR_INDEX") return "{#ERR_INDEX}"
if("ERR_UNKNOWN_CMD") return "{#ERR_UNKNOWN_CMD}"
if("ERR_LIMIT_NOT_ACCEPT") return "{#ERR_LIMIT_NOT_ACCEPT}"
if("ERR_UNKNOWN_CMD") return "{#ERR_AUTH}"
return "n/a"
}
function parseGeneric(obj) {
if(true == exeOnce){
parseNav(obj);
@ -457,7 +466,7 @@
obj.id = id
obj.token = "*"
obj.cmd = cmd
obj.val = Math.round(val*10)
obj.val = val
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj))
}
@ -477,7 +486,7 @@
tPwrAck = window.setInterval("getAjax('/api/inverter/pwrack/" + obj.id + "', updatePwrAck)", 1000);
}
else
e.innerHTML = "{#ERROR}: " + obj["error"];
e.innerHTML = "{#ERROR}: " + getErrStr(obj.error);
}
function ctrlCb2(obj) {
@ -485,7 +494,7 @@
if(obj.success)
e.innerHTML = "{#COMMAND_RECEIVED}";
else
e.innerHTML = "{#ERROR}: " + obj["error"];
e.innerHTML = "{#ERROR}: " + getErrStr(obj.error);
}
function updatePwrAck(obj) {

View file

@ -24,36 +24,6 @@
#define WAS_IN_CH_12_TO_14 "Your ESP was in wifi channel 12 to 14. It may cause reboots of your AhoyDTU"
#endif
#ifdef LANG_DE
#define INV_INDEX_INVALID "Wechselrichterindex ungültig; "
#else /*LANG_EN*/
#define INV_INDEX_INVALID "inverter index invalid: "
#endif
#ifdef LANG_DE
#define AUTH_ERROR "Authentifizierungsfehler"
#else /*LANG_EN*/
#define AUTH_ERROR "authentication error"
#endif
#ifdef LANG_DE
#define UNKNOWN_CMD "unbekanntes Kommando: '"
#else /*LANG_EN*/
#define UNKNOWN_CMD "unknown cmd: '"
#endif
#ifdef LANG_DE
#define IS_PROTECTED "nicht angemeldet, Kommando nicht möglich!"
#else /*LANG_EN*/
#define IS_PROTECTED "not logged in, command not possible!"
#endif
#ifdef LANG_DE
#define INV_DOES_NOT_ACCEPT_LIMIT_AT_MOMENT "Leistungsbegrenzung / Ansteuerung aktuell nicht möglich"
#else /*LANG_EN*/
#define INV_DOES_NOT_ACCEPT_LIMIT_AT_MOMENT "inverter does not accept dev control request at this moment"
#endif
#ifdef LANG_DE
#define PATH_NOT_FOUND "Pfad nicht gefunden: "
#else /*LANG_EN*/

View file

@ -1432,6 +1432,31 @@
"token": "INV_ACK",
"en": "inverter acknowledged active power control command",
"de": "Wechselrichter hat die Leistungsbegrenzung akzeptiert"
},
{
"token": "ERR_AUTH",
"en": "authentication error",
"de": "Authentifizierungsfehler"
},
{
"token": "ERR_INDEX",
"en": "inverter index invalid",
"de": "Wechselrichterindex ungültig"
},
{
"token": "ERR_UNKNOWN_CMD",
"en": "unknown cmd",
"de": "unbekanntes Kommando"
},
{
"token": "ERR_LIMIT_NOT_ACCEPT",
"en": "inverter does not accept dev control request at this moment",
"de": "Leistungsbegrenzung / Ansteuerung aktuell nicht m&ouml;glich"
},
{
"token": "ERR_PROTECTED",
"en": "not logged in, command not possible!",
"de": "nicht angemeldet, Kommando nicht m&ouml;glich!"
}
]
},